Blog |

Error monitoring in Golang

Error monitoring in Golang
Table of Contents

Rollbar is proud to announce its error monitoring SDK for the Go language (aka Golang). It’s an open source programming language originally created by Google and is growing in popularity. It’s a low-level language like C, but also offers garbage collection, an easy-to-use package system, and other features.

If you’re used to languages like Java or Javascript, then Go’s way of handling errors will be new to you. We will give a brief introduction on how error handling works in Go, then cover how you can monitor errors in production apps.

Using the error type

Go uses an error type to indicate an abnormal state. For example, the os.Open function returns an error value when it fails to open a file. Many people think this is more clear than throwing an error or returning a nil value.

The error type is an interface that you can implement to create your own errors. The error interface requires an Error method which returns a string. This allows you to print errors out in the console or in a log message. Specific error implementations might have additional methods.

type error interface {
  Error() string
}

Go also allows you to implement functions with multiple return values. This is commonly used to provide one value upon success, and a second value upon an error. Let’s dive into an example showing how we can handle multiple return values.

Below, the calculateSqrt function will return an error when you pass a negative number. That’s because the square root of a negative number is not defined.

func calculateSqrt(f float64) (float64, error) {
 //return an error as second parameter if invalid input
  if (f < 0) {
    return float64(math.NaN()),errors.New("Not able to take the square root of a negative number")
  }
//otherwise use default square root function
  return math.Sqrt(f),nil
}

To use this function, we call it and assign two return values separated by a comma. If there is an error, we print it out on the console. If not, then we have successfully calculated the square root.

func main() {
  ret, err  := calculateSqrt(-1)    
  if err != nil {
    fmt.Println(err)
  }else{
    fmt.Println("The square root is ", ret)
  }
}

Using defer, panic, and recover

In Go, we do not throw an exception like in Java or Javascript. Instead, a panic is created after a runtime error. Also, instead of try and catch we can use the built-in functions defer and recover to resume processing.

Let’s start with a basic description of the defer function. Defer is commonly used to simplify functions that perform clean-up actions. It pushes a function call onto a list, and the list of saved calls is executed after the surrounding function returns. The defer function can also be used in your main method to globally recover from any panic in your application. This is useful to log or track the problem for analysis.

Recover is a built-in function that is used to regain control of a panicking goroutine. It can only be called inside of a different function. Once called, it will capture information about what caused the panic and then resume normal execution.

Here is an example of how you can recover from a panic using defer:

func recoverError() {  
  if r := recover(); r!= nil {
    fmt.Println( r)
  }
}
func main() {
  defer recoverError()
}

You can learn more about these functions in Go’s official documentation: Error Handling and Defer, Panic, and Recover.

Error monitoring in production

Printing errors and panics on the console are fine ways to handle them in development. However, in production applications you don’t have access to a console. Instead, you should capture these errors and send them to an aggregation service for tracking and analysis.

Rollbar helps you monitor errors in real-world applications. It provides you with a live error feed, along with stack traces and contextual data to debug errors quickly. You can also understand user experience by tracking who is affected by each error. Learn more about our product features.

Video of Go errors in Rollbar

Below are some simple steps describing how to add Go SDK to your code. You can find more details in Rollbar’s Go documentation or the godocs.

  1. Visit https://rollbar.com and sign up for a free account if you haven’t done so yet. Next, create your project and select "Backend" then “Go” from the list of notifiers. Select the server side access token that is generated for you. You’ll need this to configure Rollbar in the steps below.
  2. Open the command prompt in your project directory and type the following command to install the Go SDK.

    go get github.com/rollbar/rollbar-go
  3. Import the Rollbar package in your code.

    import ("github.com/rollbar/rollbar-go")
  4. Add Rollbar with your access token in the main function.

    rollbar.SetToken("ACCESS-TOKEN")
    rollbar.SetEnvironment("production")
  5. Add the Rollbar method where the error is going to catch.

    func recoverError() {   
     if r := recover(); r!= nil {
       fmt.Println(r)
       rollbar.Critical(r)
       rollbar.Wait()    
     }
    }

The Wait method will block until the queue of errors or messages is empty. It’s important to make sure these errors are tracked before you exit the application so they are not lost.

Test Rollbar with an example Go app

To test that it’s working, write a program that will generate an error message. In the example below, you can generate an error by executing the program on the console.

package main
import (
  "github.com/rollbar/rollbar-go"
  "errors"
  "fmt"
  "time"
)

func recoverError() {  
  if r := recover(); r!= nil {
    fmt.Println(r)
    rollbar.Critical(r)
    rollbar.Wait()    
  }
}

func main() {
  defer catchError()
  rollbar.SetToken("ACCESS TOKEN")
  rollbar.SetEnvironment("production")
  var timer *time.Timer = nil
  timer.Reset(10) // crash
}

We have also added convenience functions called Wrap and WrapAndWait. They call a function and will recover and report a panic to Rollbar if it occurs. We recommend adding it at a high level in your code to handle panics globally.

func main() {
  rollbar.SetToken("MY_TOKEN")
  rollbar.WrapAndWait(doSomething)
}

func doSomething() {
  var timer *time.Timer = nil
  timer.Reset(10) // this will panic
}

You can check out our working example app on GitHub. To run it, clone the project and replace the access token with your project access token. To build and execute the program follow the steps below.

  1. Open the command prompt in the project directory.
  2. Type go build and press enter. It will create an exe file in the same directory if the program has been built successfully.
  3. Type the generated exe file name and press enter.

Viewing errors in Rollbar

Open Rollbar to see what these errors look like in your account’s item page. The error we just generated should be called "run time error : Invalid memory or nil". Get more details by clicking on the item. You can now see a traceback showing you the exact source code file, method, and line number that generated the error.

Screenshot of Rollbar item view

Rollbar also provides a lot of other contextual information that will help you troubleshoot and debug problems faster. Along the row of subtabs above you can get extra drill-down information on each individual occurrence, the people affected in client-side apps, and more. Rollbar’s dashboard shows you a summary of errors: how many times each occurred and how many people were affected. You can use this to keep an eye on the error rate and drill down to troubleshoot high-impact errors.

Conclusion

Go is a language growing in popularity thanks to its simplicity and speed. It has unique ways of handling errors due to its built-in error type and functions like defer and recover. When you’re running Go apps in production, it’s important to monitor for errors that could affect the availability of your service or user experience. Rollbar will help you monitor those errors, prioritize high impact ones, and capture more contextual data so you can fix problems faster.


If you haven’t already, sign up for a 14-day free trial of Rollbar and stop flying blind in production.