-
Notifications
You must be signed in to change notification settings - Fork 707
variadic Wrap #64
Comments
Thank you for raising this issue. There is a lot here so let me tackle the The way jsonrpc.Error2 works sounds terrible. Not only do they rely on a With that said I agree that even in cases where you only wrap once to If we made Wrap(err error, ...string) error this would address that My concern is how this could be misused. Every time you wrap a new stack My other concern is because wrap becomes easier to use, you don't have to I guess I'm saying that while I see the specific problem with errors from On Tue, 28 Jun 2016, 04:56 Alex Efros notifications@github.com wrote:
|
Yep, it is. But that's just to work around real issue at https://golang.org/src/net/rpc/server.go#L388 - handlers for JSON-RPC 2.0 should be able to return errors with code, message and optional data, as required by protocol. But net/rpc will convert returned by RPC handler
I'm not sure I understand the difference between these cases.
Why do you think people will wrap aggressively? If they'll use your package, then they'll use it in their own code and thus didn't need to use Wrap at all (unless they really needs to add extra description), with only exceptions for places when they get errors from 3rd-party packages. Maybe real issue is in Wrap doing two different things - add description and stack trace, while there are cases when only one (any of them) of these things is actually wanted?
At a glance you can skip adding stack trace if you detect wrapped error already has one. Or skip in case you detect current stack is a subset of already existing. But I didn't checked the code, so this may be irrelevant, sorry if this is the case. |
I'm sorry about that, I don't think this package can help. You'll have to not wrap errors produced in this path.
My thinking is you should use
Yes, the hope is that if the code is within their own projects, they'll just use if err != nil {
// handle cleanup
return err
} It is true that the use of This is part of the recommendations (in the "putting it all together" section) that I wrote about here, http://dave.cheney.net/2016/06/12/stack-traces-and-the-errors-package.
Because errors.Wrap would become easier to use because you don't need to consider the message to attach. I believe that it will become rote and people will do it "just in case". By requiring that Wrap takes a message, it requires you to think about what you want to say at that point, and makes anti patterns like
I agree with you and I talked about this in the blog post above. My concern was if Wrap became variadic it would have two unrelated responsibilities; Wrap an error with a stack trace, and Wrap an error an extra message to take context. With that said, I can see that this argument could be applied equally in the opposite direction as you have done. We could say "Wrap returns an error that wraps the provided error, returning a new error that records the stack trace at which Wrap was called. Wrap additionally adds an optional message for context". As I said above, I see the utility of this, but I worry about misuse of this and anti patterns. Those use cases are as important to me as the use cases for adding this feature.
I think there are legitimate use cases for recording the full stack trace every time one of the four functions in this package are called. Displaying or suppressing that information is the responsibility of the thing that consumes the error, it should not be something the code Wrapping or generating the error should concern itself with. |
Implementing the errors package for the first time in my project led to me to instinctively attempt to make the Wrap function variadic, as plenty of times I was returning standard lib errors but didn't want to add a context message. I didn't see the need to add a context message if the stack trace would give me enough info about the error. However what you mentioned above are definitely very valid concerns. Making Wrap variadic will make it too easy for the programmer to misuse it eventually leading to over wrapping of errors and thus over capturing of stack traces. The user will most likely do this knowing and unknowingly. As a solution why not have the Wrap function be variadic and generate the stack trace on the only on the first wrap of the error. Subsequent wraps of an error already wrapped would not append another stack trace - there is no point in appending a lower level stack trace when we have a higher/deeper one. Subsequent wraps however can definitely append another context message, but never an additional stack trace. |
#76 is surely looks better than variadic Wrap. |
I'm going to merge this into #76 and close this issue. |
Example in http://dave.cheney.net/2016/06/12/stack-traces-and-the-errors-package
is actually good example why Wrap() should be variadic - os.PathError already contains Op and Path, so there is no sense to add same thing once again, all we need here is add stack details.
Another example is jsonrpc2.Error type. It is somewhat unusual because it's Error() returns error details serialized into JSON (this is needed to pass thru net/rpc internals while keeping error details). So, if we do
errors.Wrap(jsonrpc2_err_here, "")
and then net/rpc will internally call Error() then we'll get ": {…json here…}" and that's extra ": " prefix will break restoring error details when it comes out from net/rpc.Providing variadic
errors.Wrap(err)
which didn't add any prefix will solve both issues.The text was updated successfully, but these errors were encountered: