An Alternative Approach to Error Tracing in Go
Tags: Go, Error Tracing, errtrace, Stack Traces, Return Traces
Go is a programming language known for its simplicity, efficiency, and strong support for concurrency. However, when it comes to error handling, Go developers often face challenges in tracking the source of errors. Traditional stack traces can be helpful, but they may not provide enough context, especially when errors are passed between goroutines. In this blog post, we will explore an alternative approach to error tracing in Go using the errtrace package.
Understanding the Problem:
When errors are treated as values in Go, they can be passed around like any other value. While this flexibility is beneficial, it can make it difficult to determine the origin of an error as it moves through the program. Stack traces, which are recorded at the error site, become less useful as the error propagates. By the time the error reaches the user, valuable context about its origin is lost.
The errtrace package offers a solution to this problem by providing return traces instead of stack traces. Return traces track the code path that the error took to reach the user, providing valuable context about its journey. This approach can be more useful than stack traces and has the added benefits of being faster and more lightweight.
To use errtrace, you can start by installing the package with Go modules. Once installed, you have two options for instrumenting your code: manual instrumentation or automatic instrumentation.
1. Manual Instrumentation:
In manual instrumentation, you need to import the errtrace package and wrap errors at all return sites. This can be done using the errtrace.Wrap function. It is important to note that the errtrace.Wrap function must be called within the same function that is returning the error, and not in a helper function.
2. Automatic Instrumentation:
If manual instrumentation seems like too much work, errtrace provides a tool that can automatically instrument your code. The tool can be installed separately and run on your codebase to add errtrace wrappers to all return sites.
Working with errtrace:
Once your code is instrumented with errtrace, you can print return traces for errors using the errtrace.FormatString function or by formatting the error with %+v in fmt.Printf-style functions. The return traces printed by errtrace will include the error message and the path the error took until it was printed.
errtrace is designed to have low overhead on supported systems. Benchmark results for linux/amd64 on an Intel Core i5-13600 show that errtrace scales with each frame that an error is returned through, while stack traces have a large initial cost. However, it is important to note that using errtrace may affect error comparisons and type-casting. Instead of using == to compare errors or type-casting them directly, the standard library’s errors.Is and errors.As functions should be used.
Safe Mode and Contributions:
errtrace includes an opt-in safe mode that drops unsafe operations in exchange for poorer performance. This mode can be enabled by using the safe build tag when compiling code that uses errtrace. Currently, errtrace’s unsafe operations are implemented for GOARCH=amd64 and GOARCH=arm64 only. Contributions to support unsafe mode for other architectures are welcome, and the project encourages contributors to open issues to discuss new features before making contributions.
Tracking the path of errors in Go programs can be challenging, especially when errors are passed between goroutines. The errtrace package provides a valuable alternative to stack traces by offering return traces that provide context about the error’s journey. With its low overhead and support for automatic instrumentation, errtrace is a powerful tool for Go developers who want to improve error tracking and debugging. Give it a try and see how it can enhance your error handling workflow!
 errtrace GitHub Repository: https://github.com/ztrue/errtrace
 Zig’s Error Return Traces: https://ziglang.org/documentation/master/#Error-Return-Traces
Show HN: Error return traces for Go, inspired by Zig