Error Handling

    Error handling is an indispensable part of service. In normal business development, we can think that the http status code is not in the series, it can be regarded as an http request error. It is accompanied by error messages in response, but these error messages are all returned in plain text. In addition, I will define some business errors in the business, and the common practice is to pass The two fields code and msg are used to describe the business processing results, and it is hoped that the response can be made with the json response body.

    • Business processing is normal

      1. {
      2. "code": 10001,
      3. "msg": "something wrong"
      4. }

    Previously, when we handled the login logic when the username did not exist, an error was directly returned. Let’s log in and pass a username that does not exist to see the effect.

    1. curl -X POST \
    2. http://127.0.0.1:8888/user/login \
    3. -H 'content-type: application/json' \
    4. -d '{
    5. "username":"1",
    6. "password":"123456"
    7. }'

    Next we will return it in json format

      1. $ cd common
      2. $ mkdir errorx&&cd errorx
      3. $ vim baseerror.go
      1. package errorx
      2. const defaultCode = 1001
      3. type CodeError struct {
      4. Code int `json:"code"`
      5. Msg string `json:"msg"`
      6. }
      7. Code int `json:"code"`
      8. Msg string `json:"msg"`
      9. }
      10. func NewCodeError(code int, msg string) error {
      11. return &CodeError{Code: code, Msg: msg}
      12. }
      13. func NewDefaultError(msg string) error {
      14. return NewCodeError(defaultCode, msg)
      15. }
      16. func (e *CodeError) Error() string {
      17. return e.Msg
      18. }
      19. func (e *CodeError) Data() *CodeErrorResponse {
      20. return &CodeErrorResponse{
      21. Code: e.Code,
      22. Msg: e.Msg,
      23. }
      24. }
    • Replace errors in login logic with CodeError custom errors

    • Use custom errors

      1. $ vim service/user/api/user.go
      1. func main() {
      2. flag.Parse()
      3. conf.MustLoad(*configFile, &c)
      4. ctx := svc.NewServiceContext(c)
      5. server := rest.MustNewServer(c.RestConf)
      6. defer server.Stop()
      7. handler.RegisterHandlers(server, ctx)
      8. // Custom error
      9. httpx.SetErrorHandler(func(err error) (int, interface{}) {
      10. switch e := err.(type) {
      11. case *errorx.CodeError:
      12. return http.StatusOK, e.Data()
      13. default:
      14. return http.StatusInternalServerError, nil
      15. }
      16. })
      17. fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)
      18. server.Start()
      19. }
      1. HTTP/1.1 200 OK
      2. Content-Type: application/json
      3. Date: Tue, 09 Feb 2021 06:47:29 GMT
      4. Content-Length: 40