Currently, Santekno will discuss error handling in the Golang language. We will learn from easy handling to some very complex implementations. Golang already provides easy error handling, we can also make slight modifications so that the error can be more easily understood by ourselves and the people who will collaborate with us in the future. The first thing we will do is customize Golang’s default Error
.
Golang provides a simple interface
for handling Errors
, every time there is an Error
it will be returned by Golang following the definition of the interface
.
type error interface{
Error() string
}
Create Custom Golang Error
package main
import(
"errors"
"fmt"
)
func hitungArea(radius int)(int, error){
if radius < 0 {
return 0, errors.New("Tidak boleh kurang dari nol")
}
return radius * radius, nil
}
func main() {
area, err := hitungArea(-1);
if err != nil {
fmt.Println("Terdapat kesalahan...")
return
}
fmt.Println(area)
}
In the code above, we will follow the scenario to calculate the area in a circle, we need to ensure that the radius cannot have a negative value or we can say less than zero. If the radius
value sent is negative then the returned value will be “0” and an Error
message has been defined.
In the calculateArea()
function, if it is called in the main
function it will return 2 values, namely, first the calculation value and second the Error
object. To customize Error
in the calculateArea()
function you need to add a check, if the err
object is not equal to nil
then we will display error information that we can understand. Imagine if we have an Error
that is not customized, sometimes we don’t know where the Error
occurred.
There is a little trick from Santekno too, usually to do this customization we also need the Error
information contained in the calculateArea()
function as well because it could be that if we do this customization, we end up with an Error
which we don’t actually know what the error means. like what, then in the main
function we add the Error
information in the following way:
func main() {
area, err := hitungArea(-1);
if err != nil {
fmt.Printf("Terdapat kesalahan. Err: %s", err)
return
}
fmt.Println(area)
}
Get to know “Defer”
We will first discuss defer
. See the code example below to make it easier to understand
package main
import "fmt"
func balikPesan() {
fmt.Println("Ini contoh simple penggunaan fungsi Defer")
}
func main() {
defer balikPesan()
fmt.Println("Ini baris pertama")
fmt.Println("Ini baris kedua")
fmt.Println("Ini baris ketiga")
}
In the code above we use defer
to call the returnMessage()
function which we save at the beginning before we print each line of information like the code above. What does the printed code above look like? Can anyone guess?
This is what it looks like when the code above is executed
Even though it is called at the top of main()
, the returnMessage()
function is executed after the lines in the main()
function have finished. Then the returnMessage()
function is executed at the end of the function. And that’s how defer
works in Golang.
Getting to Know “Panic”
Panic
is usually used to stop programs with customized message information. When we call panic
the instructions in the program will run as follows
- Functions currently running will be terminated (stop)
- Any function called with
defer
will be executed first - Program execution will stop
Here is a simple code for using panic
package main
import "fmt"
func jalankanPanic(){
panic("Ini contoh pesan pada situasi Panic")
fmt.Println("fungsi ini berjalan dengan selesai")
}
func main(){
jalankanPanic()
fmt.Println("fungsi main berjalan sampai selesai")
}
In the code above we call the panic
function inside the executePanic()
function. After the program is run, it will stop suddenly with terminate
. It can be seen from the results of the program above like this
The program exits on the 6th line when the panic
function runs. The panic
function is another way to notify the program that an error has occurred and instruct it to terminate with a custom error message.
Added “Defer” into “Panic” function
As explained, every time the panic
function is executed the function that uses defer
will be executed first until it is finished. Let’s look at the example program code below
package main
import "fmt"
func lakukanRecovery(){
fmt.Println("Fungsi ini untuk melakukan recovery")
}
func jalankanPanic(){
defer lakukanRecovery()
panic("Ini contoh pesan pada situasi Panic")
fmt.Println("fungsi ini berjalan dengan selesai")
}
func main(){
jalankanPanic()
fmt.Println("fungsi main berjalan sampai selesai")
}
What are the results of the program above after running it? Curious? According to the information mentioned above, the result is that the function under defer
will be executed first, let’s see below
On line 11, panic
runs, then the defer
function will be executed first before being stopped. Once panic
occurs, it will look for all defer
functions to run before stopping.
Using “Recovery”
Once a panic
situation occurs, the program will stop. In fact, in the real world, applications that stop due to errors are not good. So a mechanism is needed to recover from these errors. We need to condition recovery to avoid unwanted application termination.
The defer
function is always executed when the function is experiencing panic
or no panic
occurs. So we will create a recovery scenario in the defer
function.
Detect panic
situations
In the defer
function we have to check whether the function execution experiences panic
or not. To detect this, we will run the recover()
function. After we run the function, we will get the same error message information as the parameter value passed to the panic
function. The message will be returned as the output
function of recover()
and will not be allowed to terminate but will be controlled and the calling function will run normally. Let’s look directly at an example program
package main
import "fmt"
func lakukanRecovery() {
if pesanRecover := recover(); pesanRecover != nil {
fmt.Println(pesanRecover)
}
fmt.Println("Fungsi ini untuk melakukan recovery")
}
func jalankanPanic() {
defer lakukanRecovery()
panic("Ini contoh pesan pada situasi Panic")
fmt.Println("fungsi ini berjalan dengan selesai")
}
func main() {
jalankanPanic()
fmt.Println("fungsi main berjalan sampai selesai")
}
After running the program above, the result is that the program will give a panic
information message but the program continues to run until the end without the program stopping. It can be seen below
Conclusion
Error handling in Golang does look different compared to other languages. So we need to know several things that must be considered to handle this error. We also have to think about the mechanism for ‘recovery’ so that our program continues to run and doesn’t stop suddenly if an error occurs which results in a ‘panic’ situation.