Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling multiple errors

Tags:

go

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?

like image 636
tommyd456 Avatar asked May 21 '15 18:05

tommyd456


People also ask

How do you handle multiple exceptions?

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.

How does Python handle multiple errors?

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.

Can we handle multiple exceptions in single catch block?

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.

How do you pass multiple exceptions in catch block?

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.


1 Answers

You have 3 main options:

  1. 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.

  2. 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
  }
}
  1. Create a custom error type, since errors are just interfaces, that can have some identifier or other contextual data.

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
       ....
     }  
   }
}
like image 61
Not_a_Golfer Avatar answered Oct 05 '22 05:10

Not_a_Golfer