fbpx

Golang Error Handling Best Practices to Adopt in 2021!

Error Handling

Google launched Go as an open-source programming language in 2009. With Go, the development of software becomes easier, more efficient, and reliable. The language supports the environment just like the dynamic languages. Many famous companies that have identified the need for a deeper and more structured code have adopted Golang. 

Golang was created with a base of C language along with certain feature enhancements and changes that allow the developers to manage memory systematically. Golang is fast, easy-to-learn, and a well-scaled programming language. It is widely known for its unique approaches to error handling with Go best practices in the backend.

Best Practices of Error Handling in Golang 

Golang has many exclusive ways to handle every type of custom error. Instead of the try and catch blocks, Golang typically uses panic and recovery methods to handle errors. To free a function from its panicking state, Golang uses an in-built function ‘recover’.

The most trending and advanced error handling techniques are:

1. Error Type

The “error type” is simply a type of interface. It is a type of error variable which is itself declared as a string. The sample syntax of the same is-

type error interface {  
  Error() string
}

2. String-based Errors

These errors are created from unusual input by the user and are handled by returning a simple error details text –

err := errors.New(“math: Division with 0 won’t result a definite result.”)

The above snippet uses errors.New() with which only an error message is printed for certain types of user input mistakes.

err2 := fmt.Errorf(“math: %g cannot be divided with 0 if you want a finite result”, x)

fmt.Errorf () allows parameters to pass that can be seen in the error notification text.

3. Custom Error Handling along with data

A custom error can also be created and handled by using the function ‘Error()’ within the error interface,e.g.

Type PathErrorstruct {
  Path string
}

func (e*PathError) Error() String {
  return fmt.Sprintf(“An error related to path has occurred: %v”, e.path)
}

The PathErrorinterface implements the function Error() and thus satisfies the interface. The function returns thePathErrorstruct in the string format. This struct can be used whenever you need to throw a path error.

4. Defer, Panic and Recover Techniques

Unlike other programming languages like Java, Golang doesn’t have exceptions but it contains a similar technique known as “defer, panic and recover”. Since the uses of panic and recovery are mostly different from other languages they should only be used in exceptional situations.

Defer

Defer is a mechanism in which all the function calls are put into a stack and the deferred functions are then executed in reverse order when the main function finishes. E.g.

package main
import (“fmt”)

func main (){ 
  A()
}

func A() {
  defer fmt.Println(“A”)
  B()
}

func B() {
  defer fmt.Println(“B”)
  C()
}

func C() {
  defer fmt.Println(“C”)
}

It would be compiled and run as-

C
B
A 

Panic

The panic method is used when the current program cannot be executed normally. Thus, it stops the execution of your code. Once the panic statement is called, the program crashes with a log statement containing panic values, and the deferred functions are executed all at once. 

package main
import “fmt”

func main() {
  div(5)
}

func div(x int) {
  if x>0 {
    fmt.Printf(“div(%d) \n”, x+0/x)
    div(x-1)
  }
}

When the div() function is called with 0, the Golang will panic resulting into-

Panic: runtime error: integer divide by zero

Built-in panic functions can also be used to panic in the programs. However, panic should only be used when something unusual happens or something that a program cannot handle.

Recover

In some cases, panic is not terminated but recovered instead. Panics can also be recovered by calling a built-in recover function within the deferred function. During normal execution, the recover function will return nil and not affect. If the current program is panicking, then a call to recover will be made to recover from the panic state and will resume normal execution.

func F() {
  defer func() {
    if error := recover(); error != nil {
      fmt.Println(“Your code faced the following error: “, err)
  }()
}

5. Error handling in Functions

Mostly, errors are not handled directly in the function itself but instead, returned as error details. Since multiple return values are supported in Golang, this factor can be taken as an advantage in handling errors. E.g.

func divide(a,b float64)(float64, error) {
  if b==0 {
    return 0.0, errors.New(“Cannot be divided with 0”)
}
  return a/b, nil
}

The function call can be written as

func main() {
  num, err:= divide (100,0)
  if err!=nil {
    fmt.Printf(“Error: %s”, err.Error())
  } else {
    fmt.Println(“Number is: ”, num)
  }
}

If nil is not returned as an error, it only means that there is some problem and the error needs to be handled properly. A log message can also be sent to warn the user, re-run the function till it works or close the entire program depending upon the situation. The only disadvantage is that Golang doesn’t enforce handling errors. This means that the errors can also be ignored completely.

Conclusion

Appropriate error handling is a must for developing and releasing good software. Golang’s error handling mechanism has been the talk of the town lately because of its unusual approach unlike in other languages. But, at last, the results of the error handling approach with Golang development services are proven to be better and remarkable. 

About Author: Chandresh Patel is a CEO, Agile coach and founder of Bacancy Technology. His truly entrepreneurial spirit, skillful expertise and extensive knowledge in the Agile software development services has helped the organisation to achieve new heights of success. Chandresh is fronting the organisation into global markets in a systematic, innovative and collaborative way to fulfill custom software development needs and provide optimum quality services.