errors.Error is now an interface, implementation is hidden
This commit is contained in:
parent
122cafbc2b
commit
5f6dbf2baf
|
@ -87,29 +87,44 @@ func (pos Position) Union (other Position) Position {
|
|||
}
|
||||
|
||||
// Error is an error that contains positional information.
|
||||
type Error struct {
|
||||
Position
|
||||
Message string
|
||||
type Error interface {
|
||||
error
|
||||
Position () Position
|
||||
}
|
||||
var _ error = new(Error)
|
||||
|
||||
func (err *Error) Error () string {
|
||||
type errInternal struct {
|
||||
position Position
|
||||
message string
|
||||
}
|
||||
var _ Error = new(errInternal)
|
||||
|
||||
func (err *errInternal) Error () string {
|
||||
return err.String()
|
||||
}
|
||||
|
||||
func (err *Error) String () string {
|
||||
return fmt.Sprintf("%v: %s", err.Position, err.Message)
|
||||
func (err *errInternal) String () string {
|
||||
return fmt.Sprintf("%v: %s", err.position, err.message)
|
||||
}
|
||||
|
||||
// Format produces a formatted printout of the error, and its location.
|
||||
func (err *Error) Format () string {
|
||||
return fmt.Sprintf("%v\n%v", err, err.Position.Format())
|
||||
func (err *errInternal) Position () Position {
|
||||
return err.position
|
||||
}
|
||||
|
||||
// Errorf produces an error with a fmt'd message.
|
||||
func Errorf (position Position, format string, variables ...any) error {
|
||||
return &Error {
|
||||
Position: position,
|
||||
Message: fmt.Sprintf(format, variables...),
|
||||
func Errorf (position Position, format string, variables ...any) Error {
|
||||
return &errInternal {
|
||||
position: position,
|
||||
message: fmt.Sprintf(format, variables...),
|
||||
}
|
||||
}
|
||||
|
||||
// Format returns a formatted string representing an error. This string may take
|
||||
// up multiple lines and contain ANSI escape codes. If err does not fulfill the
|
||||
// Error interface, err.Error() is returned instead.
|
||||
func Format (err error) string {
|
||||
if err, ok := err.(Error); ok {
|
||||
return fmt.Sprintf("%v\n%v", err.Error(), err.Position().Format())
|
||||
} else {
|
||||
return err.Error()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,16 +8,15 @@ testError (test,
|
|||
`example.fspl:11:7: some error
|
||||
11 | lorem ipsum dolor
|
||||
^^^^^`,
|
||||
&Error {
|
||||
Position: Position {
|
||||
Errorf (
|
||||
Position {
|
||||
File: "example.fspl",
|
||||
Line: "lorem ipsum dolor",
|
||||
Row: 10,
|
||||
Start: 6,
|
||||
End: 11,
|
||||
},
|
||||
Message: "some error",
|
||||
})
|
||||
"some error"))
|
||||
}
|
||||
|
||||
func TestErrorTab (test *testing.T) {
|
||||
|
@ -25,16 +24,15 @@ testError (test,
|
|||
`example.fspl:11:8: some error
|
||||
11 | lorem ipsum dolor
|
||||
^^^^^`,
|
||||
&Error {
|
||||
Position: Position {
|
||||
Errorf (
|
||||
Position {
|
||||
File: "example.fspl",
|
||||
Line: "\tlorem\tipsum\tdolor",
|
||||
Row: 10,
|
||||
Start: 7,
|
||||
End: 12,
|
||||
},
|
||||
Message: "some error",
|
||||
})
|
||||
"some error"))
|
||||
}
|
||||
|
||||
func TestErrorTabInBetween (test *testing.T) {
|
||||
|
@ -42,16 +40,15 @@ testError (test,
|
|||
`example.fspl:11:8: some error
|
||||
11 | lorem ipsum dolor
|
||||
^^^^^^^^^`,
|
||||
&Error {
|
||||
Position: Position {
|
||||
Errorf (
|
||||
Position {
|
||||
File: "example.fspl",
|
||||
Line: "\tlorem\tipsum\tdolor",
|
||||
Row: 10,
|
||||
Start: 7,
|
||||
End: 14,
|
||||
},
|
||||
Message: "some error",
|
||||
})
|
||||
"some error"))
|
||||
}
|
||||
|
||||
func TestGetXInTabbedString (test *testing.T) {
|
||||
|
|
|
@ -11,6 +11,6 @@ func testString (test *testing.T, correct string, got string) {
|
|||
testcommon.Compare(test, correct, got)
|
||||
}
|
||||
|
||||
func testError (test *testing.T, correct string, err *Error) {
|
||||
testString(test, correct, err.Format())
|
||||
func testError (test *testing.T, correct string, err Error) {
|
||||
testString(test, correct, Format(err))
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue