I have Function 1:
func Function1() {
if err := Function2(); err != nil {
}
}
and Function2:
func Function2() error {
if err := doSomethingThatMightCauseError(); err != nil {
return errors.New("Error Type 1")
}
if err := doSomethingElseThatMightCauseError(); err != nil {
return errors.New("Error Type 2")
}
}
How can I detect what type of error has happened (internal, no results found in db etc) and then handle accordingly in Function 1?
If your code throws more than one exception, you can choose if you want to: use a separate try block for each statement that could throw an exception or. use one try block for multiple statements that might throw multiple exceptions.
By handling multiple exceptions, a program can respond to different exceptions without terminating it. In Python, try-except blocks can be used to catch and respond to one or multiple exceptions. In cases where a process raises more than one possible exception, they can all be handled using a single except clause.
In Java SE 7 and later, a single catch block can handle more than one type of exception. This feature can reduce code duplication and lessen the temptation to catch an overly broad exception.
If a catch block handles multiple exceptions, you can separate them using a pipe (|) and in this case, exception parameter (ex) is final, so you can't change it. The byte code generated by this feature is smaller and reduce code redundancy.
You have 3 main options:
string based, i.e. looking into the message. This is of course pretty bad because if you later change one letter in the message, you need to rewrite all the checking code, so I'd avoid it.
If the error messages can stay constant, simply create errors as global variables, and then compare the received error with a known pre-defined one.
For example:
var ErrDB = errors.New("Database Error")
var ErrTimeout = errors.New("Timeout") //or whatever
and then
if err := someFunc(); err != nil {
switch err {
case ErrDB:
//do stuff that needs to be done here
case ErrTimeout:
//etc /etc
}
}
For example:
const (
ErrDB = 1
ErrTimeout = 2
...
)
type MyError struct {
Code int
Message string
}
// This is what you need to be an error
func (e MyError)Error() string {
return e.Message
}
func NewError(s string, code int) error {
return MyError{s,code}
}
and then when you return it do something like this:
// Return a MyError with a DB code for db operations
func someFunc() error {
if err := talkToDB(); err != nil {
return NewError(err.Error(), ErrDB)
}
return nil
}
and when analyzing it:
if err := someFunc(); err != nil {
// check if this is a MyError
if me, ok := err.(MyError); ok {
// now we can check the code
switch me.Code {
case ErrDB:
//handle this
....
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With