Errors
Go error library with error portability over the network
Install / Use
/learn @cockroachdb/ErrorsREADME
cockroachdb/errors: Go errors with network portability
This library aims to be used as a drop-in replacement to
github.com/pkg/errors and Go's standard errors package. It also
provides network portability of error objects, in ways suitable for
distributed systems with mixed-version software compatibility.
It also provides native and comprehensive support for PII-free details and an opt-in Sentry.io reporting mechanism that automatically formats error details and strips them of PII.
See also the design RFC.
Table of contents:
- Features
- How to use
- What comes out of an error?
- Available error leaves
- Available wrapper constructors
- Providing PII-free details
- Building your own error types
- Error composition (summary)
- API (not constructing error objects)
Features
| Feature | Go's <1.13 errors | github.com/pkg/errors | Go 1.13 errors/xerrors | cockroachdb/errors |
|-------------------------------------------------------------------------------------------------------|---------------------|-------------------------|----------------------------|----------------------|
| error constructors (New, Errorf etc) | ✔ | ✔ | ✔ | ✔ |
| error causes (Cause / Unwrap) | | ✔ | ✔ | ✔ |
| cause barriers (Opaque / Handled) | | | ✔ | ✔ |
| errors.As(), errors.Is() | | | ✔ | ✔ |
| automatic error wrap when format ends with : %w | | | ✔ | ✔ |
| standard wrappers with efficient stack trace capture | | ✔ | | ✔ |
| transparent protobuf encode/decode with forward compatibility | | | | ✔ |
| errors.Is() recognizes errors across the network | | | | ✔ |
| comprehensive support for PII-free reportable strings | | | | ✔ |
| support for both Cause() and Unwrap() go#31778 | | | | ✔ |
| standard error reports to Sentry.io | | | | ✔ |
| wrappers to denote assertion failures | | | | ✔ |
| wrappers with issue tracker references | | | | ✔ |
| wrappers for user-facing hints and details | | | | ✔ |
| wrappers to attach secondary causes | | | | ✔ |
| wrappers to attach logtags details from context.Context | | | | ✔ |
| errors.FormatError(), Formatter, Printer | | | (under construction) | ✔ |
| errors.SafeFormatError(), SafeFormatter | | | | ✔ |
| wrapper-aware IsPermission(), IsTimeout(), IsExist(), IsNotExist() | | | | ✔ |
"Forward compatibility" above refers to the ability of this library to recognize and properly handle network communication of error types it does not know about, for example when a more recent version of a software package sends a new error object to another system running an older version of the package.
How to use
- construct errors with
errors.New(), etc as usual, but also see the other error leaf constructors below. - wrap errors with
errors.Wrap()as usual, but also see the other wrappers below. - test error identity with
errors.Is()as usual. Unique in this library: this works even if the error has traversed the network! Also,errors.IsAny()to recognize two or more reference errors. - replace uses of
os.IsPermission(),os.IsTimeout(),os.IsExist()andos.IsNotExist()by their analog in sub-packageoserrorso that they can peek through layers of wrapping. - access error causes with
errors.UnwrapOnce()/errors.UnwrapAll()(note:errors.Cause()anderrors.Unwrap()also provided for compatibility with other error packages). - encode/decode errors to protobuf with
errors.EncodeError()/errors.DecodeError(). - extract PII-free safe details with
errors.GetSafeDetails(). - extract human-facing hints and details with
errors.GetAllHints()/errors.GetAllDetails()orerrors.FlattenHints()/errors.FlattenDetails(). - produce detailed Sentry.io reports with
errors.BuildSentryReport()/errors.ReportError(). - implement your own error leaf types and wrapper types:
- implement the
erroranderrors.Wrapperinterfaces as usual. - register encode/decode functions: call
errors.Register{Leaf,Wrapper}{Encoder,Decoder}()in ainit()function in your package. - implement
Format()that redirects toerrors.FormatError(). - see the section Building your own error types below.
- implement the
What comes out of an error?
| Error detail | Error() and format %s/%q/%v | format %+v | GetSafeDetails() | Sentry report via ReportError() |
|-----------------------------------------------------------------|-------------------------------------|--------------|-------------------------------|-----------------------------------|
| main message, eg New() | visible | visible | yes (CHANGED IN v1.6) | full (CHANGED IN v1.6) |
| wrap prefix, eg WithMessage() | visible (as prefix) | visible | yes (CHANGED IN v1.6) | full (CHANGED IN v1.6) |
| stack trace, eg WithStack() | not visible | simplified | yes | full |
| hint , eg WithHint() | not visible | visible | no | type only |
| detail, eg WithDetail() | not visible | visible | no | type only |
| assertion failure annotation, eg WithAssertionFailure() | not visible | visible | no | type only |
| issue links, eg WithIssueLink(), UnimplementedError() | not visible | visible | yes | full |
| safe details, eg WithSafeDetails() | not visible | visible | yes | full |
| telemetry keys, eg. WithTelemetryKey() | not visible | visible | yes | full |
| secondary errors, eg. WithSecondaryError(), CombineErrors() | not visible | visible | redacted, recursively
