Hello everyone, my name is Xie Wei, I am a programmer.
In the near future, I will continue to update the study notes of the built-in library, mainly referring to the document GOdoc and the source code of the built-in library
The topic of this section is error
Error handling in Go is different from other languages, and the design philosophy is different. Developers often complain about error handling in Go.
This section starts from the error of the built-in library, combined with the common error handling methods of the built-in library, summarizes the error handling methods suitable for the project.
The outline
- Your own common error handling methods
- Error implemented by the built-in library
- conclusion
Summary of their own common error handling methods
1. Create a value of error type
- errors.New()
- fmt.Errorf()
These two methods can be implemented.
package main
import (
"errors"
"fmt"
"reflect"
)
func main() {
recordError := errors.New("record not found")
dbError := fmt.Errorf("%s"."db connet fail")
fmt.Println(recordError, reflect.TypeOf(recordError))
fmt.Println(dbError, reflect.TypeOf(dbError))
}
>>
record not found *errors.errorString
db connet fail *errors.errorString
Copy the code
2. Customize error types
- Implementing the Error interface
type CodeError struct {
Code int
Message string
}
func (c CodeError) Error() string {
return fmt.Sprintf(" e.Code = %d, e.Message=%s", c.Code, c.Message)
}
func Result() error {
var codeError CodeError
codeError = CodeError{
Code: 400,
Message: "connect fail",}return codeError
}
func main(){
var codeError CodeError
var err error
codeError = CodeError{
Code: 404,
Message: "http status code error",
}
err = codeError
fmt.Println(err)
}
>>
e.Code = 404, e.Message=http status code error
Copy the code
Error type, as long as the error interface can be implemented.
Take a look at the interface definition:
type error interface {
Error() string
}
Copy the code
- The concrete implementation of errors.New
func New(text string) error {
return &errorString{text}
}
// errorString is a trivial implementation of error.
type errorString struct {
s string
}
func (e *errorString) Error() string {
return e.s
}
Copy the code
That is, the errorString structure is defined and the Error method is bound
- The implementation of FMT.Errorf
func Errorf(format string, a ... interface{}) error {return errors.New(Sprintf(format, a...))
}
Copy the code
Errorf also calls errors.New.
To sum up:
- There are two ways to create an error
- At the bottom is a structure that implements the Error interface
- Custom Error type, Error method can be implemented
Error implemented by the built-in library
Errors are common and part of the business, so the built-in library implementation will also encounter errors. How to see the built-in library implementation error
1. strconv.Atoi
func main(){
number, err := strconv.Atoi("2992-121")
fmt.Println(number,err)
}
>>
0 strconv.Atoi: parsing "2992-121": invalid syntax
Copy the code
The underlying implementation is:
type NumError struct {
Func string // the failing function (ParseBool, ParseInt, ParseUint, ParseFloat)
Num string // the input
Err error // the reason the conversion failed (e.g. ErrRange, ErrSyntax, etc.)
}
func (e *NumError) Error() string {
return "strconv." + e.Func + ":" + "parsing " + Quote(e.Num) + ":" + e.Err.Error()
}
Copy the code
Define various error types:
var ErrRange = errors.New("value out of range")
var ErrSyntax = errors.New("invalid syntax")
func syntaxError(fn, str string) *NumError {
return &NumError{fn, str, ErrSyntax}
}
func rangeError(fn, str string) *NumError {
return &NumError{fn, str, ErrRange}
}
func baseError(fn, str string, base int) *NumError {
return &NumError{fn, str, errors.New("invalid base " + Itoa(base))}
}
func bitSizeError(fn, str string, bitSize int) *NumError {
return &NumError{fn, str, errors.New("invalid bit size " + Itoa(bitSize))}
}
Copy the code
That is, the core defines a structure that implements the error interface
2. net/http
func main(){
response, err := http.Get("https://space.bilibili.com/10056291/#/")
fmt.Println(response, err)
}
Copy the code
The underlying error types are:
type Error struct {
Op string
URL string
Err error
}
func (e *Error) Error() string { return e.Op + "" + e.URL + ":" + e.Err.Error() }
Copy the code
That is, a structure is defined to implement the error interface.
In view of reading the underlying error type in the built-in library, modify your own error type setting method
type ExampleError struct {
Err error
Code int
Message string
}
func (e *ExampleError) Error() string {
return fmt.Sprintf("e.Code = %d e.Err = %s e.Message = %s", e.Code, e.Err.Error(), e.Message)
}
func ExampleResult() error {
return &ExampleError{
Err: errors.New("what the fucking life"),
Code: 502,
Message: "what the fucking life",}}Copy the code
conclusion
- There are two ways to create an error value
- The Error type that oneself define, need to realize Error method only, realize Error interface can
Others: Here are some suggestions for error handling
- For each library, common errors can be declared at the beginning of the library file
var ErrorIndexOut = errors.New("index out of range")
var ErrorFuck = errors.New("fucking life")
Copy the code
- Variables of the wrong type can be taken
Err
orError
mark - It is recommended that error types be handled uniformly, that is, complete projects declare their own library handling modules, rather than randomly creating errors within the project
After < >
- The first iteration of back end engineer walkthrough is underway