SoFunction
Updated on 2025-03-04

Best practices for error and exception handling in Go

mistake

Recognize the error

In Go, an error is a type of program error state. Contains status information at the runtime and compile time of the program. Generally, when we write Go code, we will encounter the following processing methods.

file, err := ("")
(file)
if err != nil {
(err)
return
}

We use the os library to create a file named, which returns an error message for a file pointer or err.

err indicates the error message when the file creation fails. When storing errors, we will handle the program errors; when there is no error, other logical codes will be executed normally.

Custom errors

In Go, we allow us to customize error messages. Custom error messages need to use the New() function in the error report provided.

The following example code:

package main

import (
"errors"
"fmt"
)
func printError() (a int, err error) {
err = ("Print error message")
a = 1
return
}
func main() {
i, err := printError()
("i value is", i)
if err != nil {
(err)
return
}
}

Specific printing information:​i value is 1 Print error message​。

Implementation principle

In use​()​​When function is used, a structure is declared in the package​errorString​And implement the method in the error interface body​Error()​​。

// errors packagepackage errors
func New(text string) error {
return &errorString{text}
}
type errorString struct {
s string
}
func (e *errorString) Error() string {
return 
}
// error interfacetype error interface {
Error() string
}

abnormal

Recognize abnormalities

The exception is the programCompile time​or​Runtime​Exception information that occurred. If the exception is not processed, the program may terminate the program or throw exception information, causing the program to fail to run normally. Whether it is when the program is compiled or run, exceptions need to be strictly processed.

With the following code, the program will trigger an exception when compiling, resulting in the inability to compile normally:

package main

import "fmt"

func main() {
panic("print panic")
("end")
}

Print result:

╰─ go run
panic: print panic

goroutine 1 [running]:
()
/usr/local/var/www/go/golang_code/src/syntax/err/:20 +0x39
exit status 2

  • The Go runtime triggers the runtime panic, and a value of interface type is thrown along with the program crash. There is a RuntimeError() method for this error value to distinguish ordinary errors.
  • panic can be initialized directly from the code: when the error condition (the code we tested) is very strict and unrecoverable and the program cannot continue to run, a panic function can be used to generate a run-time error that aborts the program.
  • panic receives a parameter that does any type, usually a string, which is printed when the program dies. The Go runtime is responsible for aborting the program and giving debugging information.
  • Calling panic in multi-layer nested function calls can immediately abort the execution of the current function.

Handle exceptions

When an exception occurs during the program, the normal operation of the program will be terminated. Exception information needs to be strictly processed. In Go, you can use recover() to obtain exception information from panic and obtain the execution rights of the program.

  • As the name suggests, this (recover) built-in function is used to recover from panic or error scenarios: allows the program to regain control from panicking, stop the termination process and resume normal execution.
  • recoverOnlyUsed in defer-modified functions: used to obtain the error value passed in the panic call. If it is executed normally, calling recover will return nil, and there is no other effect.
  • panic will cause the stack to be expanded until the defer modified recover() is called or the program is aborted.
  • All defer statements guarantee execution and return control to the function caller receiving panic. This bubbles upwards until the top layer, and executes (of each layer) defer, the program crashes at the top of the stack, and reports the error situation on the command line with the value passed to panic: this termination process is panicking.

Exception handling principles

  • Inside the package, it should be recovered from panic: explicit panic() outside the scope of the package is not allowed. Inside the package, especially when there are deep nested calls in non-exported functions, it is useful for the main call function to use panic to represent error scenarios that should be translated into errors (and improves code readability).
  • Outside the package, return an error value (not panic) to the package's caller.
  • The principle of the Go library is that even if panic is used inside the package, it must be handled with recover to return an explicit error in its external interface (API).

Exception handling practice

The following example code triggers a panic() in the called function printPanic(), uses defer in the main() function to receive panic() information, and performs exception handling of panic().

package main
import "fmt"
func printPanic() {
panic("panic exception")
}

func main() {
defer func() {
err := recover()
if err != nil {
("panic is", err)
}
}()

printPanic()

("end")
}

Print result:

╰─ go run
i value is 1
Print error message

This is the article about the best practices for errors and exception handling in Go. For more related Go exception handling content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!