The error type is an interface. You can return values that contain contextual information as long as the error value you return has an Error() method returning a string.
type ParseError struct {
line int
}
func (e ParseError) Error() string {
return "Parse error at line: " + fmt.Sprint(e.line)
}
Note: The current release may vary slightly on the details. I'm using a pre-release build. But older versions are similar.
And then in the code for handling the error, you can do
switch err.(type) {
case db.IOError:
// Database exception here
case io.FileNotFoundError:
// File exception
default:
// Pass it to our caller for them to handle.
return nil, err
}
Which gives you the ability to selectively catch errors based on type.
Do you mean that exceptions, when they bring down your program, indicate the line where the exception was thrown? If so, then `panic` in Go does the same thing.
Using goroutines and panic/recover, you can do the same things you do with try/catch/throw.
No; the point is that the information is contextual. For a database failure, the information will be DB specific; for an IO failure, IO specific; for an IO failure in the DB subsystem, it will be information about IO failure wrapped in info about the DB failure.
I think too many people get wrong idea about exceptions from defaults in many environments. Exceptions being thrown should not normally be a sign of a bug; knowing the line number the exception thrown should be irrelevant information almost all the time, save for errors like access violations or null pointer exceptions.
Instead, the information contained in an exception can usually be turned into actionable data to a user or administrator of an app (depending on whether it's on the client or server).