...

Source file src/github.com/gin-gonic/gin/errors_test.go

Documentation: github.com/gin-gonic/gin

     1  // Copyright 2014 Manu Martinez-Almeida. All rights reserved.
     2  // Use of this source code is governed by a MIT style
     3  // license that can be found in the LICENSE file.
     4  
     5  package gin
     6  
     7  import (
     8  	"errors"
     9  	"fmt"
    10  	"testing"
    11  
    12  	"github.com/gin-gonic/gin/internal/json"
    13  	"github.com/stretchr/testify/assert"
    14  )
    15  
    16  func TestError(t *testing.T) {
    17  	baseError := errors.New("test error")
    18  	err := &Error{
    19  		Err:  baseError,
    20  		Type: ErrorTypePrivate,
    21  	}
    22  	assert.Equal(t, err.Error(), baseError.Error())
    23  	assert.Equal(t, H{"error": baseError.Error()}, err.JSON())
    24  
    25  	assert.Equal(t, err.SetType(ErrorTypePublic), err)
    26  	assert.Equal(t, ErrorTypePublic, err.Type)
    27  
    28  	assert.Equal(t, err.SetMeta("some data"), err)
    29  	assert.Equal(t, "some data", err.Meta)
    30  	assert.Equal(t, H{
    31  		"error": baseError.Error(),
    32  		"meta":  "some data",
    33  	}, err.JSON())
    34  
    35  	jsonBytes, _ := json.Marshal(err)
    36  	assert.Equal(t, "{\"error\":\"test error\",\"meta\":\"some data\"}", string(jsonBytes))
    37  
    38  	err.SetMeta(H{ //nolint: errcheck
    39  		"status": "200",
    40  		"data":   "some data",
    41  	})
    42  	assert.Equal(t, H{
    43  		"error":  baseError.Error(),
    44  		"status": "200",
    45  		"data":   "some data",
    46  	}, err.JSON())
    47  
    48  	err.SetMeta(H{ //nolint: errcheck
    49  		"error":  "custom error",
    50  		"status": "200",
    51  		"data":   "some data",
    52  	})
    53  	assert.Equal(t, H{
    54  		"error":  "custom error",
    55  		"status": "200",
    56  		"data":   "some data",
    57  	}, err.JSON())
    58  
    59  	type customError struct {
    60  		status string
    61  		data   string
    62  	}
    63  	err.SetMeta(customError{status: "200", data: "other data"}) //nolint: errcheck
    64  	assert.Equal(t, customError{status: "200", data: "other data"}, err.JSON())
    65  }
    66  
    67  func TestErrorSlice(t *testing.T) {
    68  	errs := errorMsgs{
    69  		{Err: errors.New("first"), Type: ErrorTypePrivate},
    70  		{Err: errors.New("second"), Type: ErrorTypePrivate, Meta: "some data"},
    71  		{Err: errors.New("third"), Type: ErrorTypePublic, Meta: H{"status": "400"}},
    72  	}
    73  
    74  	assert.Equal(t, errs, errs.ByType(ErrorTypeAny))
    75  	assert.Equal(t, "third", errs.Last().Error())
    76  	assert.Equal(t, []string{"first", "second", "third"}, errs.Errors())
    77  	assert.Equal(t, []string{"third"}, errs.ByType(ErrorTypePublic).Errors())
    78  	assert.Equal(t, []string{"first", "second"}, errs.ByType(ErrorTypePrivate).Errors())
    79  	assert.Equal(t, []string{"first", "second", "third"}, errs.ByType(ErrorTypePublic|ErrorTypePrivate).Errors())
    80  	assert.Empty(t, errs.ByType(ErrorTypeBind))
    81  	assert.Empty(t, errs.ByType(ErrorTypeBind).String())
    82  
    83  	assert.Equal(t, `Error #01: first
    84  Error #02: second
    85       Meta: some data
    86  Error #03: third
    87       Meta: map[status:400]
    88  `, errs.String())
    89  	assert.Equal(t, []any{
    90  		H{"error": "first"},
    91  		H{"error": "second", "meta": "some data"},
    92  		H{"error": "third", "status": "400"},
    93  	}, errs.JSON())
    94  	jsonBytes, _ := json.Marshal(errs)
    95  	assert.Equal(t, "[{\"error\":\"first\"},{\"error\":\"second\",\"meta\":\"some data\"},{\"error\":\"third\",\"status\":\"400\"}]", string(jsonBytes))
    96  	errs = errorMsgs{
    97  		{Err: errors.New("first"), Type: ErrorTypePrivate},
    98  	}
    99  	assert.Equal(t, H{"error": "first"}, errs.JSON())
   100  	jsonBytes, _ = json.Marshal(errs)
   101  	assert.Equal(t, "{\"error\":\"first\"}", string(jsonBytes))
   102  
   103  	errs = errorMsgs{}
   104  	assert.Nil(t, errs.Last())
   105  	assert.Nil(t, errs.JSON())
   106  	assert.Empty(t, errs.String())
   107  }
   108  
   109  type TestErr string
   110  
   111  func (e TestErr) Error() string { return string(e) }
   112  
   113  // TestErrorUnwrap tests the behavior of gin.Error with "errors.Is()" and "errors.As()".
   114  // "errors.Is()" and "errors.As()" have been added to the standard library in go 1.13.
   115  func TestErrorUnwrap(t *testing.T) {
   116  	innerErr := TestErr("some error")
   117  
   118  	// 2 layers of wrapping : use 'fmt.Errorf("%w")' to wrap a gin.Error{}, which itself wraps innerErr
   119  	err := fmt.Errorf("wrapped: %w", &Error{
   120  		Err:  innerErr,
   121  		Type: ErrorTypeAny,
   122  	})
   123  
   124  	// check that 'errors.Is()' and 'errors.As()' behave as expected :
   125  	assert.True(t, errors.Is(err, innerErr))
   126  	var testErr TestErr
   127  	assert.True(t, errors.As(err, &testErr))
   128  }
   129  

View as plain text