Basics of Go

panic, defer, & Error Design Pattern

Maximiliano Firtman

Maximiliano Firtman

Independent Consultant
Basics of Go

Check out a free preview of the full Basics of Go course

The "panic, defer, & Error Design Pattern" Lesson is part of the full, Basics of Go course featured in this preview video. Here's what you'd learn in this lesson:

Maximiliano demonstrates Go's less common control flow mechanisms, panic and defer, along with design patterns for error handling. These mechanisms involve triggering runtime errors, halting program execution, and deferring function evaluations.


Transcript from the "panic, defer, & Error Design Pattern" Lesson

>> We have the init function. We already mentioned that, you can have more than one per package. It will be executed as soon as possible. Then we have panic and defer. Let's see what that is. Panic sounds interesting, right? For example, you can panic when you feel like your age is getting into, I don't, know, 50, 40, 30.

It depends on where you are, you'll always have a panic age close to you. Well, actually, we can say if it's greater than 140, maybe, yeah, something's happening, so you can panic. And what's panic? Panic, it's actually like an interruption, you're aborting. In this case, you are saying, hey, I cannot continue.

It's like throwing an exception, if you want. The only problem is that on the other side, we don't have try-catch, okay? So actually panic will, you can send a message. You can say, why are you panicked? Too old to be true. I don't know.
>> [LAUGH]
>> Your panic, the panic goes up in the call stack and it depends, if no one is doing anything with that, there are ways to trap that panic, right, but it's not a try-catch.

Basically, what will happen is that it will close your app with a message saying panic, okay? And that's how you do panic. This is how you do error management? No, no, this is not how you do error management. Panic is, I have an invalid state, I cannot do what you are asking, but I wasn't expecting an error.

If you're expecting an error, because it's common you have an error on that situation, you don't panic, okay? We will see what do you do? And then we mentioned defer. That's another thing that you have here. What's defer? Well, in this case we don't have yet a nice code to use it.

We will use one in a second. But actually when you call defer, it's defer on something else. So you can defer something. I don't know, you can defer, call Println("Bye!!"), something like that. So if I execute this, you can see that Bye!!, it's actually being executed at the end, and even if it's the first line of main.

So in this case, it's going to defer the execution of that sentence until the end of the function call is reached. That's all. And you can have more than one defer. They're going to be stacked. So I'm gonna say, "Good" "Bye". But it's not what you were expecting, right?

>> [LAUGH]
>> No way. It says "Bye", and then "Good". First thing [SOUND], you look like that meme that is kind of making all weird calculations. Now it's "Bye" "Good". So actually, it's last in first out, if you want, first in last out, anyway. Typically you use this for a lot of situations where you will forget to do something.

Example, you open a database. Typically you need to close the database, right? Well, typically you forget to close the database. So when you open the database, immediately, you close it. But you defer that, so then you won't forget. You open, you close in the same line, but you say, hey, when this ends, please close it.

And also it works with panics. If there is a panic, it will execute your defers before closing the app. Okay, so if within the function call there was a panic call that you know that we won't continue, it will honor your defers anyway. It's like a finally in the try-catch, well, kind of, okay?

So these are curiosities of function execution, okay, that might change the standard function execution that we're used to. Again, this is not yet error management, okay? In fact, now it's time to talk about that. So let's say we need to read a user from a database, from a file, doesn't matter.

We receive an ID, and we need to return a user. This is the design pattern, we're not going to return the user, we are returning a pair. We're returning two values, a possible user and a possible error option, okay? And what's the idea? You are going to return the user or nil.

This is kind of pseudo code as it is right now. We will see that we will have to make some small changes on this, but you understand the idea first, okay? Again, this is the design pattern. It's not really part of the language. But the libraries, the standard libraries are using these design patterns and we should follow also these design patterns.

So if we could get what we were supposed to get, we return with the object and and a nil for the error. If there was an error, we don't return the object, so we have a nil, and then the error description. For those of you with experience with Node.js, we have a similar situation there, a similar error management on Node.js.

This case, typically, there is a callback. I'm talking about Node.js without promises. There is a callback and that callback also has two arguments, the error and the object, it's similar in some ways, okay? We will write this right now, okay? But that's the idea. That's one use case for returning more than one value, error management, okay?

Make sense? Right here, I have an example of named automatic returns. We have already seen that in action with probably the same sample, actually. So we can move on.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now