Migrate from cockroachdb/errors¶
For most of a module this is an import-path change. The names and signatures match deliberately, so the compiler will find anything that is not.
The change¶
grep -rl '"github.com/cockroachdb/errors"' --include="*.go" . \
| xargs sed -i 's|"github.com/cockroachdb/errors"|"gitlab.com/phpboyscout/go/errors"|'
go get gitlab.com/phpboyscout/go/errors
go mod tidy
go build ./... && go test ./...
That is the whole migration for a module that uses only the common surface.
forge moved this way — 19 files, 84 references, no code changes.
What carries over unchanged¶
New · Newf · Errorf · Wrap · Wrapf · WithStack · Is · As ·
Unwrap · WithHint · WithHintf · WithDetail · GetAllHints ·
GetAllDetails · FlattenHints · FlattenDetails · Join
Three behaviour differences¶
Join gains a shape it did not have¶
cockroachdb's Join wraps its aggregate in a stack wrapper, so the value it
returns does not satisfy Unwrap() []error. This one does, as the standard
library does.
If you were reaching through it by hand, stop:
// before — the double unwrap cockroachdb needs
joined.(interface{ Unwrap() error }).Unwrap().(interface{ Unwrap() []error }).Unwrap()
// after
joined.(interface{ Unwrap() []error }).Unwrap()
More usefully: hints, details and attributes attached below a Join are now
readable. They were not before. If you worked around that, the workaround can go.
Sentinels need NewSentinel¶
A package-level var Err… = errors.New(…) captures a stack at package
initialisation — pointing at runtime.doInit, never at where the error was
returned. Change those, and only those:
// before
var ErrNotFound = errors.New("not found")
// after
var ErrNotFound = errors.NewSentinel("mypkg.not_found", "not found")
Find them with:
Keep New everywhere else — inside a function it is doing the right thing. See
Declare a sentinel for what the kind string is for.
auth.env-style ladders are gone, and so is Sentry¶
This package resolves nothing and reports to nothing. If you relied on
cockroachdb's Sentry reporting, that belongs in
go/observability.
What is not here¶
errorspb and the protobuf encoding, gRPC and HTTP status mapping, Sentry
reporting, redaction interplay, domains, barriers, telemetry keys, context tags.
None had a call site in this estate. Wire serialization arrives later as a
sibling module — the core is already shaped for it — and telemetry belongs to
go/observability.
Sequence the estate leaf-first¶
Migrating one module does not reduce its dependency count, because
cockroachdb/errors returns through any sibling that still uses it. Measured:
forge alone went from 376 transitive packages to 377.
Migrate the leaves first — httpclient, grpcclient, transport-openapi,
workspace, config-keychain, tls, which have 21 call sites between them —
and the graph clears from the bottom up. httpclient is the one that matters:
it is what puts cockroachdb/errors back into forge.
Expect the dependency count to stay flat until most of a graph has moved. That is the migration working, not failing.