Error handling is now done with a custom error in the file package
This commit is contained in:
parent
2ea0c86c54
commit
a755fc9f41
72
file/error.go
Normal file
72
file/error.go
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
package file
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type ErrorKind int
|
||||||
|
|
||||||
|
const (
|
||||||
|
ErrorKindError ErrorKind = iota
|
||||||
|
ErrorKindWarn
|
||||||
|
)
|
||||||
|
|
||||||
|
type Error struct {
|
||||||
|
Location
|
||||||
|
width int
|
||||||
|
message string
|
||||||
|
kind ErrorKind
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewError creates a new error at the specified location.
|
||||||
|
func NewError (
|
||||||
|
location Location,
|
||||||
|
width int,
|
||||||
|
message string,
|
||||||
|
kind ErrorKind,
|
||||||
|
) (
|
||||||
|
err *Error,
|
||||||
|
) {
|
||||||
|
return &Error {
|
||||||
|
Location: location,
|
||||||
|
width: width,
|
||||||
|
message: message,
|
||||||
|
kind: kind,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error returns a formatted error message as a string.
|
||||||
|
func (err Error) Error () (formattedMessage string) {
|
||||||
|
switch err.kind {
|
||||||
|
case ErrorKindError:
|
||||||
|
formattedMessage += "ERR"
|
||||||
|
case ErrorKindWarn:
|
||||||
|
formattedMessage += "!!!"
|
||||||
|
}
|
||||||
|
|
||||||
|
// print information about the location of the mistake
|
||||||
|
if err.width > 0 {
|
||||||
|
formattedMessage += fmt.Sprint (
|
||||||
|
" ", err.Location.row + 1,
|
||||||
|
":", err.Location.column + 1)
|
||||||
|
}
|
||||||
|
formattedMessage += " in " + err.Location.file.path + "\n"
|
||||||
|
|
||||||
|
if err.width > 0 {
|
||||||
|
// print erroneous line
|
||||||
|
formattedMessage +=
|
||||||
|
err.Location.file.lines[err.Location.row] + "\n"
|
||||||
|
|
||||||
|
// print an arrow with a tail spanning the width of the mistake
|
||||||
|
columnCountdown := err.Location.column
|
||||||
|
for columnCountdown > 0 {
|
||||||
|
formattedMessage += " "
|
||||||
|
columnCountdown --
|
||||||
|
}
|
||||||
|
for err.width > 1 {
|
||||||
|
formattedMessage += "-"
|
||||||
|
}
|
||||||
|
formattedMessage += "-\n"
|
||||||
|
}
|
||||||
|
formattedMessage += err.message + "-\n"
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
44
file/file.go
44
file/file.go
@ -1,11 +1,8 @@
|
|||||||
package file
|
package file
|
||||||
|
|
||||||
import "os"
|
import "os"
|
||||||
import "log"
|
|
||||||
import "bufio"
|
import "bufio"
|
||||||
|
|
||||||
var logger = log.New(os.Stderr, "", 0)
|
|
||||||
|
|
||||||
// File represents a read only file that can print out formatted errors.
|
// File represents a read only file that can print out formatted errors.
|
||||||
type File struct {
|
type File struct {
|
||||||
path string
|
path string
|
||||||
@ -104,47 +101,6 @@ func (file *File) Close () {
|
|||||||
file.file.Close()
|
file.file.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
// mistake prints an informational message about a mistake that the user made.
|
|
||||||
func (file *File) mistake (column, row, width int, message, symbol string) {
|
|
||||||
logger.Print(symbol)
|
|
||||||
|
|
||||||
// print information about the location of the mistake
|
|
||||||
if width > 0 {
|
|
||||||
logger.Print(" ", row + 1, ":", column + 1)
|
|
||||||
}
|
|
||||||
logger.Println(" in", file.path)
|
|
||||||
|
|
||||||
if width > 0 {
|
|
||||||
// print erroneous line
|
|
||||||
logger.Println(file.lines[row])
|
|
||||||
|
|
||||||
// print an arrow with a tail spanning the width of the mistake
|
|
||||||
for column > 0 {
|
|
||||||
logger.Print(" ")
|
|
||||||
column --
|
|
||||||
}
|
|
||||||
for width > 1 {
|
|
||||||
logger.Print("-")
|
|
||||||
}
|
|
||||||
logger.Println("^")
|
|
||||||
}
|
|
||||||
logger.Println(message)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error prints an error at row and column spanning width amount of runes, and
|
|
||||||
// a message describing the error. If width is zero, neither the line nor the
|
|
||||||
// location information is printed.
|
|
||||||
func (file *File) Error (column, row, width int, message string) {
|
|
||||||
file.mistake(column, row, width, message, "ERR")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Warn prints a warning at row and column spanning width amount of runes, and
|
|
||||||
// a message describing the error. If width is zero, neither the line nor the
|
|
||||||
// location information is printed.
|
|
||||||
func (file *File) Warn (column, row, width int, message string) {
|
|
||||||
file.mistake(column, row, width, message, "!!!")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Location returns a location struct describing the current position inside of
|
// Location returns a location struct describing the current position inside of
|
||||||
// the file. This can be stored and used to print errors.
|
// the file. This can be stored and used to print errors.
|
||||||
func (file *File) Location () (location Location) {
|
func (file *File) Location () (location Location) {
|
||||||
|
@ -7,13 +7,3 @@ type Location struct {
|
|||||||
row int
|
row int
|
||||||
column int
|
column int
|
||||||
}
|
}
|
||||||
|
|
||||||
// Error prints an error at this location.
|
|
||||||
func (location Location) Error (width int, message string) {
|
|
||||||
location.file.Error(location.column, location.row, width, message)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Warn prints a warning at this location.
|
|
||||||
func (location Location) Warn (width int, message string) {
|
|
||||||
location.file.Warn(location.column, location.row, width, message)
|
|
||||||
}
|
|
||||||
|
Reference in New Issue
Block a user