Description
(I previously made a comment about this which I am now turning into full proposal.)
I have been following the #51365 issue for some time and was really happy that it landed. But now I tried to finally update code to use the new API and I was a bit surprised by it, primarily that it makes it hard to work with logic which expects that the error is context.Canceled
and at the same time be able to retrieve the error at the end.
What I mean is that I have code which 1) obtains the error from the context, then it 2) passes it through by returning the error through a chain of function call returns, and then 3) inspects the error and determines that it is about the context cancellation and wants to obtain the cause for it (e.g., log it).
Now, the tricky thing is that at point 3) I cannot know both if the error is context cancellation and what was the cause. I can do that only at point 1).
Options to me seems to be:
- At point 1) do
errors.Join(ctx.Err(), context.Cause(ctx))
, but this is ugly if there was no cause, becausecontext.Cause(ctx) in that case returns the same as
ctx.Err()`, so I am joining two same errors. So more logic to combine only if they are different. Also returned error message is ugly. - I could use
gitlab.com/tozd/go/errors
's WrapWith which was made so that one error can be made a cause of another error, without modifying either of them. The error message is nicer, but the logic to check if they are different has still to be added.
I understand that originally ctx.Err
could not return an context.Canceled
error which would unwrap to the cause error to assure that err == context.Canceled
continues to work. But why not make context.Cause
return such an error already? So in my view, it would be better if context.Cause
returned:
- Same error as
ctx.Err
if there is no cause. - An error which satisfies both
context.Is(context.Canceled)
and can be unwrapped to the cause error. This can be done by having a customIs
method on the error.
For context.Cause
returned errors we do not have to assure that err == context.Canceled
holds.
I am not sure if we can still change context.Cause
now? Probably not? But could we then introduce yet another context.CauseError
or something, which would return an error with the behavior above? It can probably be made in 3rd party library as well, it is not too long, but I think it would be great to have it in standard library.
Metadata
Metadata
Assignees
Type
Projects
Status