Problem
os package has helpers like IsNotFound or IsExists, and the trace package has a similar facility. It has issues:
- It is not compatible with how
os helpers work. This constantly introduces subtle logic errors, where the code behaves differently based on how the error was wrapped, as opposed to what the error is.
- HTTP errors are thrown away and replaced with trace's own internal error structures.
trace also keeps messing with the original error message, sometimes prefixing it with its own prefix, or sometimes (like with HTTP) by replacing it completely, this prevents trace to be used by API clients who rely on meaningful error bodies (JSON) and also prevents HTTP servers from returning user-facing errors.
Proposal
At this point (after fixing several issues in Teleport caused by this) I am firmly convinced there is a better approach:
trace should drop its own error structures
- helpers like
trace.IsNotFound() should work by examining the original error, instead of checking for the correct wrapper
trace should stop attaching its own "error message" on top of what's already inside the original error. The original error's message should always be preserved and delivered as-is without any alterations.
End Result
If implemented, this proposal will:
- Make
trace easier to use as well. The usage will be dead-simple: just call trace.Wrap(err) everywhere.
- Checking with helpers like
trace.IsNotFound() will always work, even for errors that weren't wrapped.
Problem
ospackage has helpers likeIsNotFoundorIsExists, and the trace package has a similar facility. It has issues:oshelpers work. This constantly introduces subtle logic errors, where the code behaves differently based on how the error was wrapped, as opposed to what the error is.tracealso keeps messing with the original error message, sometimes prefixing it with its own prefix, or sometimes (like with HTTP) by replacing it completely, this preventstraceto be used by API clients who rely on meaningful error bodies (JSON) and also prevents HTTP servers from returning user-facing errors.Proposal
At this point (after fixing several issues in Teleport caused by this) I am firmly convinced there is a better approach:
traceshould drop its own error structurestrace.IsNotFound()should work by examining the original error, instead of checking for the correct wrappertraceshould stop attaching its own "error message" on top of what's already inside the original error. The original error's message should always be preserved and delivered as-is without any alterations.End Result
If implemented, this proposal will:
traceeasier to use as well. The usage will be dead-simple: just calltrace.Wrap(err)everywhere.trace.IsNotFound()will always work, even for errors that weren't wrapped.