Building Resilient Go Applications: Key Error Handling Techniques

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] the next step is air handling and we've got to have a really big big conversation about air handling because we need to have a very clear understanding of what air handling means to us before we can sort of implement it into the system so let's have that conversation for me error handling means three things handling and error means three things you might have more but I think these are the three core things that have to happen uh when a piece of code is handling an error the first thing that happens is that error has to be locked and that error only gets logged once once not multiple times so so if code is going to handle an error then it's its job to log that error number two the error has to be reviewed and it has to be determined whether or not um that go routine or the program itself now needs to be terminated can the eror can we recover from the error that's really the second question can we recover can we we do something to put the state of that go routine or the app back in and keep going or is this particular go routine or app done and we've got to shut this thing down that has to be determined and the last thing here is that the error doesn't propagate anymore if you're handling the error once you're done handling it it's not an error anymore you might produce a new error from that that's fair but that error shouldn't propagate anymore all right so these are the things that we're looking at for air handling now one other way I kind of look at air handling is as a signaling mechanic and I want to share that with you um when you think about channels for a second let's go back to like channels when we talk about channels we talk about the idea that a channel really implements a signaling semantic that's why we always say receiver and sender there's a there's a go routine sending a signal across that channel and so it's a signaling semantic however when it comes to channels the signaling semantic in this case I would call it a horizontal signaling semantic it's horizontal signaling it's one g to another G I think of ER handling as signaling as well but instead of this idea of a horizontal signaling I think of it as vertical signaling I want to share that with you now back in the early early days of go rob Pike wrote a blog post about errors in go and he said something that at the time I had zero clue it was so simple but it didn't make any sense to me it didn't mean anything Rob Pike said errors are just values period done errors are just values it didn't mean anything to me for several years and now I understand how profound that statement is I want you to think about errors and go as just values and that value could have any sort of state and be behavior that is needed to help us identify the full context of the problem so we can determine how to deal with it I want you to think about errors as values that signal information about a problem that's occurring in the system I think of error values as signals very much as the way we think about values going through a channel these are values going through the call stack through the interface the error interface which for me acts like a pipeline of receiving of sending and receiving these error signals and so every single error value represents a different sort of error signal about a problem that's occurring and hopefully it has the full context to allow us to make the best informed decision on how to handle the error so let me give you an example let's say we've got some a function in the application layer it's calling a function into the business layer which calls a function into the foundation layer which calls a function into the standard library right we're even Crossing layers here and every one of these functions has the typical uh error interface type as the return and so the way I think about that error interface is like this I think of the error interface as this pipe now what happens let's say we're down here in the call stack and we made some standard Library call and it's failing so what does the standard Library do it constructs some concrete type and what it does is it takes this concrete type and it puts it into the error interface some concrete type and it passes it up to the calling function now we've all seen error not equals nil what does this actually mean error not equals nil let's explore that for a second we know that all interfaces and go all interface values regardless of the name of the type is a two-word data structure two-word data structure where each word is a pointer the first pointer points to another data structure that we call the it table and the second pointer points to whatever the concrete type value is that's being stored inside the interface now it tables are too technical so even though there's a point to here what I like to do is just say that the first word represents the type of value being stored and the second word is a pointer to that value of that type that type could be value semantics or pointer semantics but this is what we have now when an interface value is empty or set to its zero value both of these pointers are nil but when there's a value stored inside the the interface they're not nil so when you see error not equals nil what I want you to do is read that as is there a value stored inside the error interface I want you to read that as is there a concrete value stored inside because if there is a concrete value stored inside what does that mean we got an error there's no concrete value we're clean so this is nil this is not nil so is there a value stored inside the air interface is there a value stored inside the pipeline are we being signaled to value now in this case this foundational level function is going to say what oh yeah yeah there's a value stored there damn we've got a problem now every function has to make a decision am I going to handle the error now based on the policies and the rules I've given you so far is this function allowed to handle the error no that's right Camille no why because that function is not allowed to log because it's in the foundation layer and part of handling an error means logging it so in all reality no no Foundation level code is actually allowed to handle errors if you're not allowed to handle an error then what do you do you have only one choice you have to wrap it with more context and send it back up the pipeline send the signal and so what F has to do now is take this error and wrap it with more context and send it up now here's a business layer function and it says hey there's an error in the is there concrete value stored inside the error interface the answer is yes we're being signaled an error now the business layer says um do I want to handle this error and the business layer is allowed to handle it because it's allowed to log so it says yes I'm going to handle the error so what does it do it logs the error it looks at the error to determine what it needs to do the more granular your error signals are the more granular the response can be but less is also more so we don't want to be we don't we don't want to have 30 of these signals but you know a handful remember the rule of five three to five signals can work very very well and then it does whatever the logic is related to that error even determining if we need to shut down a go routine or an app and then when it returns because it's going to handle the error the error stops IT returns we're good now that that's what it has to do it either terminates or it says we're good pretty cool so I want to think about errors as signals different signals mean different things and we can build logic around this idea that if we get an error signal of this type we do this error signal of this type we do that and thanks to the fact that this is a web API we can do all of that air handling in a piece of middleware at the business level and make sure that the handlers don't ever do any airor handling at all they need to pass all the air handling to the airor middleware so we have consistency and no problem if I see any handlers doing any sort of air handling that's going to stop a code review right away so this is our logic this is our understanding now with all of that we need to think about the different error signals that we want for this web application I will tell you that right now we have essentially three custom error types or signals the first one is what I call an application error or what I like to call sometimes is a known error why do I call it it a known error how many times h i shouldn't say known I apologize the word isn't known the word is trusted I apologize I called an app an app error or or another word for it is a trusted error I'll ask we get to that question at the break a trusted error why do I use that word trusted how many times have you been in a restaurant and saw the the point of sales system blow up and they gave you way too much information about what the problem was times you walk near a gas station and they're using window machines and it's blown up and they've given you way too much information airports okay any asp.net app here's the problem right too much information tends to be made public when things fail information that really isn't trusted so if the system sees an error that it doesn't know it should only be returning a 500 with no information whatsoever because the risk is too great but we do need an error signal or an error type that we that we are going to consider is trusted we trust the information that's inside of it to be delivered back to the caller we have to be very careful with these trusted errors we have to make sure that we're not leaking information but we do need this sort of trusted error at times because we do have to provide information so somebody can correct what they're doing so we're going to have our non-trusted and then we're going to have our trusted errors we're going to have two more signals as well we're going to have what I'm going to call a shutdown signal there needs to be a single point of code where we can signal the application itself to shut down when we've identified an Integrity issue and that point of code has to also have some sort of checks and balances around it to give you an example of this though most recent recently one of the team members at Arden was working on some um was using a third party package that had an API that they were forced to use that if it failed it called Panic think about foundational level code that calls panic when things fail and guess what things fail this was a total nightmare no one is allowed to no foundational or business code in general should be allowed to just shut down the app especially like that I do believe though that code in any layer should have the right to Signal a shutdown to say I think we have a big problem here and I think this application needs to be shut down signaling a shutdown is fine actually doing it has to be localized and controlled and checked in our case we're going to have the web framework actually contain even though it's a foundation layer will contain the uh shutdown signaling if it receives a signal of that type and we'll have some checks and balances around that we'll Implement that first and then the last um signal which we will not Implement today will be data validation signaling we've got to be able to set send an error back to the caller when they give us a data model that's not formatted correctly so that's another sort of data model validation signal which we'll get to at some point those are the three that I have here um that we're going to implement it doesn't mean that you might not have more but I think those three are core to everything that we do okay with all that being said let's start with the shutdown signal first so the question is do we think that the shutdown error signal is that foundational or business I'm going to make it foundational because I'm going to integrate it into the web framework again there's no right or wrong answer there but the more things we put in the foundation then the stronger the policy is for something which in sometimes is really good in other words but sometimes having such a strong policy on something makes things inflexible right in which case we want to move it to the business layer business layer means that we're giving every project its ability to Define what they want to do in terms of policy when we put it into the foundation we're saying no you don't get to choose we're choosing for you
Info
Channel: Ardan Labs
Views: 1,300
Rating: undefined out of 5
Keywords:
Id: HF3scbk7a_Q
Channel Id: undefined
Length: 17min 23sec (1043 seconds)
Published: Mon Jun 24 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.