SoFunction
Updated on 2025-03-03

Detailed explanation of error handling and exception mechanism of re-learning Go language

As developers, we cannot guarantee that the program will never have exceptions during operation. For exceptions, in many programming languages, it can be usedtry-catchStatements are used to capture, and the developers of Go language obviously thinktry-catchBeing abused, soGoNot supported for usetry-catchStatement captures exception handling.

So, how does Go define and handle program exceptions?

Go language divides the problems that occur when running a program into two types: errors (error) and exceptions (exception), an error is one of the expected results of the operation of a program (such as a function). When you call a function, you should handle the error situation, and the exception is unpredictable (of course it can also be triggered manually) and will cause serious errors to interrupt the program.

Go Error Handling Policy

When writing a Go language program, it is generally recommended to tell the caller whether the function is successfully executed by the last return value of the function. It can be discussed in two situations:

In the first case, if the execution result of the function is only correct and failed, the return value can bebooleantype:

func exists(key string) bool {
	//to check if the key is exists
	return true
}
if ok := exists("test"); ok {
	// do something
}

In the second case, if you want to get the caller to get more detailed error information, it is obviously not enough to return a boolean value, and you can return aerrortype,errorType is an interface, only oneErrorMethod interface:

type error interface {
	Error() string
}

passerrorType ofErrorMethods can obtain more detailed error information, which facilitates callers to handle further, soGoThe methods and functions of the standard library are generally includederrorTypes are the last return value, such as what we mentioned in our previous articlesosPackedOpenandCreatefunction:

package os
func Open(name string) (*File, error) {
	return OpenFile(name, O_RDONLY, 0)
}
func Create(name string) (*File, error) {
	return OpenFile(name, O_RDWR|O_CREATE|O_TRUNC, 0666)
}

When the last function returns the valueerrorNot fornilWhen , it means that the execution is unsuccessful, and other return values ​​should be ignored at this time:

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

In the above code, iferrorNot fornil, then variablesfileThennil, means that a file handle cannot be obtained, and an error is returned directly, because if you continue to execute it, the program may crash.

Of course not all cases returnerrorNot fornil, you must discard other return values, such as usingRead()When reading a file:

Read(p []byte) (n int, err error)

When reading the file to the endReadThe method will return aError:

var EOF = ("EOF")

AlthougherrorNot fornil, but the read byte array should still be saved instead of discarding it.

Several ways to create an error

When we develop our own functions, we can also create our own error types, and there are several ways:

errors package

errorsPackedNew()Functions can create a text-onlyerrortype:

func getFile(name string)(*,error){
	if name == ""{
		return nil,("file name could not be empty") 
	}
}

fmt package

fmtPackedErrorfFunctions can format text as error information and return an error type, so its function is similar to the function.

func getFile(name string)(*,error){
	if name == ""{
		return nil,("file name could not be empty")
	}
}

Functions can also encapsulate other functionserrorType, return a new oneerrorType to form a complete error chain:

doc, err := ()
()
if err != nil {
	return nil, ("parsing %s as HTML: %v", url,err)
}

Custom error type

In fact, the above two ways to create error types are essentially implemented.errorInterface, we can also create aErrorThe method type to implementerrorinterface:

type Result struct {
	Code    int
	Message string
	Data    interface{}
}
func (r Result) Error() string {
	return 
}

How to handle errors

When the call function or method returns the return value iserrorWhen it comes to types, of course, you can choose to ignore the error directly, but the more appropriate way is to deal with the corresponding errors. There are several processing strategies:

Return the error directly

For a function, if an error is encountered during execution, it can be returned directly to the upper caller:

func SendMessage(url string) error {
	if url == ""{
		return ("url can't not be empty")
	}
	_, err := (url)
	if err != nil {
		return err
	}
	return nil
}

Log and continue running

When the returned error is encountered when calling the function, if it does not affect the program's operation, you can also choose to record the error log and execute it as follows:

if err := SendMessage("https://xxx/sendMessage");err != nil{
	("the message sending been broken by : %v\n", err)
}

Log and end the run

If an error affects the execution of the program, you can also log the log and exit the execution of the program:

if err := SendMessage("https://xxx/sendMessage");err != nil{
	("the message sending been broken by : %v\n", err)
	(1)
}

Record the log and exit the execution, use it directlylogPackedFatalfFunctions can do it, so the simpler way of the above code is:

if err := SendMessage("https://xxx/sendMessage");err != nil{
	("the message sending been broken by : %v\n", err)
}

Go exception handling mechanism

In Go language, exceptions refer to errors that will cause a program to crash and cannot continue running, such as array out of bounds or null pointer reference, which will triggerpanicabnormal:

package main
func main() {
	var s = []int{1, 2, 3}
	s[3] = 10
}

The above program runs as follows, and it can be seen that the array cross-border exception is triggered:

panic: runtime error: index out of range [3] with length 3

Whether in the main coroutine or child coroutine, once triggeredpanicException, the entire program will be terminated.

panic function

Unpredictable exceptions such as array cross-border will be automatically triggeredpanic, can also be called manuallypanicThe function triggers an exception to terminate the program's run:

func loadConfig(path string){
	panic("can't load the config file on path " + path)
}

It is best not to call a good program on its own initiative.panicFunctions, especially when developing class libraries, are best to returnerrorType to tell the caller what error occurred, not to triggerpanicCauses the program to terminate operation.

Recover function

When it happenspanicWhen an exception is not caught, the program will terminate the run. In Go language, it can be used.deferStatements andrecoverFunction pattern to capturepanicabnormal:

package main
import (
	"fmt"
	"log"
)
func main() {
	n1 := FindElementByIndex(1)
	(n1)
	n2 := FindElementByIndex(4)
	(n2)
}
func FindElementByIndex(index int) int {
	defer func() {
		if e := recover(); e != nil {
			(e)
		}
	}()
	s := []int{1, 2, 3, 4}
	return s[index]
}

summary

When calling a function, the error is the result of execution and should be handled in time, while exceptions are often uncontrollable and can be captured using the defer+recover mode.

This is the article about the detailed explanation of error handling and exception mechanism of re-learning Go language. For more related Go error handling and exception mechanism content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!