Go is 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 Rollbar.
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.
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.
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.
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
- Import the Rollbar package in your code.
import ("github.com/rollbar/rollbar-go")
- Add Rollbar with your access token in the main function.
rollbar.SetToken("ACCESS-TOKEN")
rollbar.SetEnvironment("production")
- 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.
Open the command prompt in the project directory.
Type
go build
and press enter. It will create an exe file in the same directory if the program has been built successfully.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.
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. Sign up for a free trial and stop flying blind in production.
Top comments (0)