What's the proper way to wrap errors in Go?

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
what's the difference between errors.wrap F errors dot error F and fmt Dot error f I'm going to answer that hi I'm Jonathan Hall today's video is inspired by this post on stack Overflow this was posted a couple of years ago and I actually replied to the post and I gave an answer but I thought it would make sense to dive in a little bit more in a video here so that's what I'm going to do today so now actually the first thing about this particular question is it makes an incorrect assumption the question asks about three functions in the standard Library errors.rap f errors dot error F and fmt Dot error f however if we actually look at the standard Library we'll see that those functions don't actually exist there so here I'm looking at the errors package in the standard Library and it's a very very small package you see there's only a few functions as is new and unwrap for functions so that wrap F and the error F don't come from here where do they come from well I'm glad you asked they come from this package this package is called github.com PKG slash errors now this package was predominantly written by Dave Cheney which we can see by looking over here at the GitHub contributors chart back in 2016 and some updates in 2019 Dave Cheney wrote this package and of course it's a public open source package so others have contributed I think my name's on here somewhere huh there it is but let's let's talk about what the package does and how it's different from the standard library now something really important to keep in mind when considering this is that this package is fairly old was first written back in it looks like 2015-16 and the go standard library has changed somewhat significantly since then especially as it relates to error handling but let's look at what this package does and I'll explain a little bit of the history about it and and why there's maybe room for confusion in this original stack Overflow question so here I am on the godoc page for the github.com PKG errors package and of course there's a lot of information here at the top level but then let's look at the index because that sort of gives us a nice overview of what the package does now first thing we can see is it has an as function there's also this is and unwrap and new now those are the same four functions we just saw in the standard Library so those are duplicated here but what else do we have we have something called cause oh there's that error F that was being asked about and then we have a few others here with these width functions with message with message f with stack wrap and wrap F the other one we were asked about in the question and then some other types A Frame and stack Trace so the first thing to be aware of about this package is that this was created with the idea of the ability to wrap errors which did not previously exist or at least not in a well-defined way in the go standard library and if we look at the change log for go 1.13 we'll see that they added something called error wrapping and here we can see that they added some functions to the standard Library they added errors.is errors.as and errors dot unwrap so three of the four functions in the standard libraries error package were added in go 1.13 prior to that you basically had new and that was kind of all you had there keep that context in mind when we look back at the PKG errors godoc maybe it starts to make a little bit more sense let's look at it again now we have as is unwrap and the truth is these were added in the in this package also around the same time for compatibility with a standard Library if we look at the Historical versions of the same package we can see the older versions I'm going to jump back in time to January 3rd 2019. this is well before goes standard Library supported error wrapping and we'll see that the errors the PKG errors package has a much smaller interface now you see there's no is as or unwrap instead of these other functions so let me talk about what these functions did in the past because that will help explain why they're no longer necessary and what they were replaced by again the basic concept of this package was the ability to wrap errors and that that's so that you can take one error from from some function you called wrap it with your own contacts and pass it up this up the call chain so that was done prior to go 113 with this package let's look at some of the function signatures uh with message here for example this allows you to specify an existing error and then a new message of your own then the error that's returned contains your new message and the old error that could be unwrapped somehow how do you unwrap the original error you can use this cause function and that pulls the original error out of an error if it's if it's there right just like with message you could use with message F that would allow you to use formatting just like printf or S printf and then we have with stack which would allow you to attach a stack Trace to an error without adding a message I'll talk more about that in a moment and then we have these wrap and wrap F functions that work just like combining with message or with message f with the stack uh so I'm gonna talk about the stack tracing uh wrapping in a moment we'll get back to that but the the important message right now is that this package handled error wrapping and it gave us several points to do that before the go standard Library did so when the ghost standard Library added uh error wrapping support this package wanted to remain compatible so it added those new functions we saw a moment ago so that's when this package added as and is an unwrap because those are the methods that the standard Library uses to allow wrapping and unwrapping errors now at the same time that the standard Library added the is as an unwrap functions to the errors package they added a new capability to the existing fmt.rrf function in the fmt package so let's talk about that now prior to go 113 this function did exist and it worked well it was just essentially the a way to call errors.new without having to call fmt.s printf for example if you wanted to use some formatting in your error message now you're probably already familiar with using percent s and percent D and so on in a formatting string for f printf or s printf or just printf when you want to format a string or a number for example but they added this new verb called percent W that sort of magically lets you wrap an error so now you can call fmt.error F and put a percent W somewhere in your format string typically at the end but it can go anywhere and as long as that corresponds with an error value in the list of arguments it wraps that error rather than just treating it as a string so let me demonstrate with my own example here on the go playground this is just some throwaway code but it shows it demonstrates the point here my function Foo tries to open a file and if it fails to open a file then it wraps that error with the fmt dot error app here so you can see I've added my own uh descriptive text here failed to open file colon under percent W and then that percent W corresponds with the error value if we run the code then we see here the error failed to open file that's my text and then open food.txt colon no such folder directory that's the original error message now the advantage of doing it with percent W as opposed to say percent S as we would have done and go 1.12 or earlier is that it becomes possible to unwrap that error using the unwrap function in the standard Library so where does that leave us okay so github.com PKG errors was a very popular package probably still is uh it has been largely though not completely obsoleted by GO 1.13's error wrapping support almost obsoleted okay what's left so remember earlier I mentioned this with stack function what does that do well it attaches a stack Trace to an error it doesn't change the representation of the error in the sense that if you call uh the errors method on the error it will return the same string whatever message was in there before however it adds an extra function to that error implementation type that can be used to extract a stack Trace let's see how that's done so here's the part of the documentation of the github.com PKG errors package that explains how you can retrieve the stack Trace from an existing error it uses this interface remember errors are interfaces uh that's the definition of an error and go it's an interface with the error method on it but you can of course include additional methods on your interfaces so that's how this package adds a stack Trace is it it returns an error implementation that has an additional method with a stack Trace so if you want to find that stack Trace then you you can use this little bit of code right here you basically do a type assertion on your error to see if it matches the stack Tracer uh or this this interface here and if it does then you can call the stack trace on it and it will return the stack Trace where that error was generated or or where uh with stack was called so that's the key functionality that the standard Library does not support yet uh there was talk back in the go 113 days of whether or not to include stack traces and it was declined I suppose that there were too many nuances in in different ways that you might want to to do that or represent a stack trace and they didn't decide on a standard format so that's not in the standard Library so let's recap prior to go 1.13 if you wanted to to wrap errors github.com PKG errors was a great way to do it and you would do that by using errors.rop F and errors.error F as of go 1.13 that's no longer necessary if your only goal is wrapping errors so you may as well just use fmt.error f in the standard library and then to unwrap you can use errors dot unwrap or more likely errors.pass and errors.is read the documentation for details the one exception is if you want to include stack traces in your errors then using the github.com PKG errors package may still make sense or maybe you want to implement your own stack Trace formatting or capabilities in your own package but I think that's a pretty good explanation of the difference between these three functions and when you should use one or the other which one do I use I usually like having stack traces in my errors so I often use github.com PKG slash errors that's such a mouthful or my own implementation sometimes depending on my circumstances I think that wraps it up for this question uh if you have any questions about my explanation leave a comment below if you enjoy this sort of detailed explanation be sure to subscribe and if you learned something hit the like button I hope to see you next time foreign [Music]
Info
Channel: Boldly Go
Views: 5,003
Rating: undefined out of 5
Keywords:
Id: MRbhtMptago
Channel Id: undefined
Length: 11min 16sec (676 seconds)
Published: Tue Nov 08 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.