---
# System prepended metadata

title: Error Handling Revamp

---

Error Handling Revamp
===

## Overview

Displaying and reporting errors in Prysm should be as user-friendly as possible. We must make sure that users are able to include the stack trace in Github issues and that the error logs we provide are informative, helpful and, most of all, **not too scary**.

This document outlines a few ideas to make everyone's "error life" easier.

## Improvements

### 1. Use `github.com/pkg/errors.New` instead of `errors.New`

Errors created with`errors` include only a message, whereas errors created with `github.com/pkg/errors` include also a stack trace, which is much better for debugging and logging. There is no reason to use `errors.New`.

**Action Items**
- Replace usages of `errors.New` with `github.com/pkg/errors.New` in the existing codebase.
- Write a static analyzer similar to `cryptorand` that will trigger an error whenever `errors.New` is used.

### 2. Use `log.Error(err)` for logging and `fmt.Sprintf("%+v\n", err)` to dump the stack trace to a log file

As described in the "Fprint and Print have been removed" section of https://dave.cheney.net/2016/06/12/stack-traces-and-the-errors-package, the `%+v` formatting verb can be used to print an error from `github.com/pkg/errors`, including the stack trace. Instead of scaring the user the stack trace, we can log out the message string and save the whole stack trace to a file on disk. These log files can be then uploaded onto Github as attachments to issues.

**Action Items**
- Use the `log.Error(err)` + `fmt.Sprintf("%+v\n", err)` pattern in `main` and goroutines.
- Extract the pattern to a helper function in a shared package.

**Open Questions**
- Where to store log files for each system?

### 3. Make error messages more user-friendly

Users should be informed what actions they can take when they encounter an error. Simply displaying the error message is not enough, especially if the stack trace, which is much more useful for debugging, gets saved to a log file.

**Action Items**
- Wrap all error logs in a standard, user-friendly information. This information should include the path to the saved log file, a link to Github and basic instructions on what to do next.

### 4. Do not store errors in package-level variables

Consider the following example:
```
package foo

import (
	"github.com/pkg/errors"
)

var e = errors.New("error from foo") // line 7

func F() error {
    return e
}
```

Calling this function results in a stack trace such as this:
```
error from foo
github.com/prysmaticlabs/prysm/beacon-chain/foo.init
	beacon-chain/foo/foo.go:7 // line of declaration, not line of error!
runtime.doInit
	GOROOT/src/runtime/proc.go:6265
runtime.doInit
	GOROOT/src/runtime/proc.go:6242
runtime.doInit
	GOROOT/src/runtime/proc.go:6242
runtime.main
	GOROOT/src/runtime/proc.go:208
runtime.goexit
	GOROOT/src/runtime/asm_amd64.s:1371
```
The stack trace displays information from the time when the error was created, which is during package intialization. This is definitely not useful. The "Sentinel errors" section in https://dave.cheney.net/2016/04/27/dont-just-check-errors-handle-them-gracefully describes such errors as an anti-pattern.

**Open Questions**
- This pattern is used extensively throughout the codebase and changing it would require a lot of work. Is it worth it?
- How exactly can this pattern be replaced? Is there a one-size-fits-all solution or will we have to proceed case by case? 