refactor(errs): introduce per-backend Classifier framework#183
Conversation
|
|
Replaces the implicit context.Canceled handling in IsRetryable with an
explicit single-pass Classify call driven by per-backend classifiers.
Controllers still own classification via the framework constructors
(NewUserError / NewRetryableError / NewDependencyError /
NewRetryableDependencyError); for errors a controller does not wrap,
the consumer now runs errs.Classify(err, classifiers...) once per
failing delivery, and downstream IsRetryable / IsUserError /
IsDependencyError become plain type checks.
errs.Classify walks the chain in two passes: pass 1 short-circuits on
any existing framework wrap so an explicit controller verdict always
wins; pass 2 runs the configured classifiers per node, outermost-first,
and prepends the matching framework wrap.
Adds two starter classifiers:
- core/errs/generic — context.Canceled -> InfraRetryable so graceful
shutdowns nack for redelivery instead of rejecting to DLQ.
- core/errs/mysql — server error numbers, driver.ErrBadConn,
sql.ErrConnDone/TxDone, and net.Error values. The classifier never
returns User; constraint violations stay Infra and must be wrapped
explicitly by the controller when they reflect bad user input.
Wires both into the orchestrator's consumer.New call.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
| // Pass 1 — cheap framework-wrap check. If any node already carries a | ||
| // framework type, the chain is interpretable as-is and classifiers are | ||
| // never invoked. | ||
| for cur := err; cur != nil; cur = errors.Unwrap(cur) { |
There was a problem hiding this comment.
do we expect mutli-errors to work in this case?
There was a problem hiding this comment.
what are multi-errors? This function inspects the whole error chain, same as Errors.As/Is does
There was a problem hiding this comment.
errors.Join(...) stuff which returns array of errors... i don't think we are doing it anywhere yet, just making sure if we do it later at some point, i can be calssified..
Summary
Implements an error classification framework in
core/errs: per-backendClassifierimplementations recognise raw driver/library errors and the consumer runs a singleerrs.Classify(err, classifiers...)pass after each delivery. DownstreamIsRetryable/IsUserError/IsDependencyErrorbecome plain type checks; an explicit framework wrap from a controller always wins over any classifier.errs.Classifierinterface,Verdictenum, anderrs.Classify(two-pass: framework-wrap short-circuit, then classifier walk).core/errs/generic—context.Canceled→ retryable infra.core/errs/mysql— server error numbers,driver.ErrBadConn,sql.ErrConnDone/TxDone,net.Error. Never returnsUser; controllers wrap constraint violations withNewUserErrorexplicitly.consumer.Newwires both classifiers.core/errs/README.mddocuments the framework, adding classifiers, and controller overrides.Test plan
🤖 Generated with Claude Code