1070 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			1070 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			Go
		
	
	
	
package errors
 | 
						||
 | 
						||
import (
 | 
						||
	"context"
 | 
						||
	"errors"
 | 
						||
	"fmt"
 | 
						||
	"reflect"
 | 
						||
	"strconv"
 | 
						||
	"testing"
 | 
						||
 | 
						||
	"code.30cm.net/digimon/library-go/errors/code"
 | 
						||
 | 
						||
	"github.com/golang/mock/gomock"
 | 
						||
	"github.com/stretchr/testify/assert"
 | 
						||
	"github.com/zeromicro/go-zero/core/logx"
 | 
						||
	"google.golang.org/grpc/codes"
 | 
						||
	"google.golang.org/grpc/status"
 | 
						||
)
 | 
						||
 | 
						||
func TestFromGRPCError_GivenStatusWithCodeAndMessage_ShouldReturnErr(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	s := status.Error(codes.Code(102399), "FAKE ERROR")
 | 
						||
 | 
						||
	// act
 | 
						||
	e := FromGRPCError(s)
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, uint32(10), e.Scope())
 | 
						||
	assert.Equal(t, uint32(2300), e.Category())
 | 
						||
	assert.Equal(t, uint32(2399), e.Code())
 | 
						||
	assert.Equal(t, "FAKE ERROR", e.Error())
 | 
						||
}
 | 
						||
 | 
						||
func TestFromGRPCError_GivenNilError_ShouldReturnErr_Scope0_Cat0_Detail0(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	var nilError error = nil
 | 
						||
 | 
						||
	// act
 | 
						||
	e := FromGRPCError(nilError)
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, uint32(0), e.Scope())
 | 
						||
	assert.Equal(t, uint32(0), e.Category())
 | 
						||
	assert.Equal(t, uint32(0), e.Code())
 | 
						||
	assert.Equal(t, "", e.Error())
 | 
						||
}
 | 
						||
 | 
						||
func TestFromGRPCError_GivenGRPCNativeError_ShouldReturnErr_Scope0_CatGRPC_DetailGRPCUnavailable(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	msg := "GRPC Unavailable ERROR"
 | 
						||
	s := status.Error(codes.Code(codes.Unavailable), msg)
 | 
						||
 | 
						||
	// act
 | 
						||
	e := FromGRPCError(s)
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.Unset, e.Scope())
 | 
						||
	assert.Equal(t, code.CatGRPC, e.Category())
 | 
						||
	assert.Equal(t, uint32(codes.Unavailable), e.Code())
 | 
						||
	assert.Equal(t, msg, e.Error())
 | 
						||
}
 | 
						||
 | 
						||
func TestFromGRPCError_GivenGeneralError_ShouldReturnErr_Scope0_CatGRPC_DetailGRPCUnknown(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	generalErr := errors.New("general error")
 | 
						||
 | 
						||
	// act
 | 
						||
	e := FromGRPCError(generalErr)
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.Unset, e.Scope())
 | 
						||
	assert.Equal(t, code.CatGRPC, e.Category())
 | 
						||
	assert.Equal(t, uint32(codes.Unknown), e.Code())
 | 
						||
}
 | 
						||
 | 
						||
func TestToGRPCError_GivenErr_StatusShouldHave_Code112233(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	e := LibError{scope: 11, code: 2233, msg: "FAKE MSG"}
 | 
						||
 | 
						||
	// act
 | 
						||
	err := ToGRPCError(&e)
 | 
						||
	s, _ := status.FromError(err)
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, 112233, int(s.Code()))
 | 
						||
	assert.Equal(t, "FAKE MSG", s.Message())
 | 
						||
}
 | 
						||
 | 
						||
func TestInvalidFormat_WithStrings_ShouldHasCatInputAndDetailCode(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	Scope = 99
 | 
						||
	defer func() {
 | 
						||
		Scope = code.Unset
 | 
						||
	}()
 | 
						||
 | 
						||
	// act
 | 
						||
	e := InvalidFormat("field A", "Error description")
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.CatInput, e.Category())
 | 
						||
	assert.Equal(t, code.InvalidFormat, e.Code())
 | 
						||
	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
	assert.Equal(t, e.Error(), "invalid format: field A Error description")
 | 
						||
}
 | 
						||
 | 
						||
func TestInvalidFormatL_WithStrings_ShouldHasCatInputAndDetailCode(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	Scope = 99
 | 
						||
	defer func() { Scope = code.Unset }()
 | 
						||
	ctrl := gomock.NewController(t)
 | 
						||
	defer ctrl.Finish()
 | 
						||
 | 
						||
	ctx := context.Background()
 | 
						||
	// act
 | 
						||
	e := InvalidFormatL(logx.WithContext(ctx), "field A", "Error description")
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.CatInput, e.Category())
 | 
						||
	assert.Equal(t, code.InvalidFormat, e.Code())
 | 
						||
	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
	assert.Contains(t, e.Error(), "field A")
 | 
						||
	assert.Contains(t, e.Error(), "Error description")
 | 
						||
}
 | 
						||
 | 
						||
func TestInvalidRange_WithStrings_ShouldHasCatInputAndDetailCode(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	Scope = 99
 | 
						||
	defer func() {
 | 
						||
		Scope = code.Unset
 | 
						||
	}()
 | 
						||
 | 
						||
	// act
 | 
						||
	e := InvalidRange("field A", "Error description")
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.CatInput, e.Category())
 | 
						||
	assert.Equal(t, code.InvalidRange, e.Code())
 | 
						||
	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
	assert.Equal(t, e.Error(), "invalid range: field A Error description")
 | 
						||
}
 | 
						||
 | 
						||
func TestInvalidRangeL_WithStrings_ShouldHasCatInputAndDetailCode(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	Scope = 99
 | 
						||
	defer func() { Scope = code.Unset }()
 | 
						||
	ctrl := gomock.NewController(t)
 | 
						||
	defer ctrl.Finish()
 | 
						||
 | 
						||
	ctx := context.Background()
 | 
						||
	// act
 | 
						||
	e := InvalidRangeL(logx.WithContext(ctx), "field A", "Error description")
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.CatInput, e.Category())
 | 
						||
	assert.Equal(t, code.InvalidRange, e.Code())
 | 
						||
	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
	assert.Contains(t, e.Error(), "field A")
 | 
						||
	assert.Contains(t, e.Error(), "Error description")
 | 
						||
}
 | 
						||
 | 
						||
func TestNotValidImplementation_WithStrings_ShouldHasCatInputAndDetailCode(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	Scope = 99
 | 
						||
	defer func() {
 | 
						||
		Scope = code.Unset
 | 
						||
	}()
 | 
						||
 | 
						||
	// act
 | 
						||
	e := NotValidImplementation("field A", "Error description")
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.CatInput, e.Category())
 | 
						||
	assert.Equal(t, code.NotValidImplementation, e.Code())
 | 
						||
	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
	assert.Equal(t, e.Error(), "not valid implementation: field A Error description")
 | 
						||
}
 | 
						||
 | 
						||
func TestNotValidImplementationL_WithStrings_ShouldHasCatInputAndDetailCode(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	Scope = 99
 | 
						||
	defer func() { Scope = code.Unset }()
 | 
						||
	ctrl := gomock.NewController(t)
 | 
						||
	defer ctrl.Finish()
 | 
						||
 | 
						||
	l := logx.WithContext(context.Background())
 | 
						||
	// act
 | 
						||
	e := NotValidImplementationL(l, "field A", "Error description")
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.CatInput, e.Category())
 | 
						||
	assert.Equal(t, code.NotValidImplementation, e.Code())
 | 
						||
	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
	assert.Contains(t, e.Error(), "field A")
 | 
						||
	assert.Contains(t, e.Error(), "Error description")
 | 
						||
}
 | 
						||
 | 
						||
func TestDBError_WithStrings_ShouldHasCatDBAndDetailCodeDBError(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	Scope = 99
 | 
						||
	defer func() {
 | 
						||
		Scope = code.Unset
 | 
						||
	}()
 | 
						||
 | 
						||
	// act
 | 
						||
	e := DBError("field A", "Error description")
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.CatDB, e.Category())
 | 
						||
	assert.Equal(t, code.DBError, e.Code())
 | 
						||
	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
	assert.Contains(t, e.Error(), "field A")
 | 
						||
	assert.Contains(t, e.Error(), "Error description")
 | 
						||
}
 | 
						||
 | 
						||
func TestDBDataConvert_WithStrings_ShouldHasCatDBAndDetailCodeDBDataConvert(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	Scope = 99
 | 
						||
	defer func() {
 | 
						||
		Scope = code.Unset
 | 
						||
	}()
 | 
						||
 | 
						||
	// act
 | 
						||
	e := DBDataConvert("field A", "Error description")
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.CatDB, e.Category())
 | 
						||
	assert.Equal(t, code.DBDataConvert, e.Code())
 | 
						||
	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
	assert.Contains(t, e.Error(), "field A")
 | 
						||
	assert.Contains(t, e.Error(), "Error description")
 | 
						||
}
 | 
						||
 | 
						||
func TestResourceNotFound_WithStrings_ShouldHasCatResource_DetailCodeResourceNotFound(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	Scope = 99
 | 
						||
	defer func() {
 | 
						||
		Scope = code.Unset
 | 
						||
	}()
 | 
						||
 | 
						||
	// act
 | 
						||
	e := ResourceNotFound("field A", "Error description")
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.CatResource, e.Category())
 | 
						||
	assert.Equal(t, code.ResourceNotFound, e.Code())
 | 
						||
	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
	assert.Contains(t, e.Error(), "field A")
 | 
						||
	assert.Contains(t, e.Error(), "Error description")
 | 
						||
}
 | 
						||
 | 
						||
func TestInvalidResourceFormat_WithStrings_ShouldHasCatResource_DetailCodeInvalidResourceFormat(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	Scope = 99
 | 
						||
	defer func() {
 | 
						||
		Scope = code.Unset
 | 
						||
	}()
 | 
						||
 | 
						||
	// act
 | 
						||
	e := InvalidResourceFormat("field A", "Error description")
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.CatResource, e.Category())
 | 
						||
	assert.Equal(t, code.InvalidResourceFormat, e.Code())
 | 
						||
	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
	assert.Contains(t, e.Error(), "field A")
 | 
						||
	assert.Contains(t, e.Error(), "Error description")
 | 
						||
}
 | 
						||
 | 
						||
func TestInvalidResourceState_OK(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	Scope = 99
 | 
						||
	defer func() {
 | 
						||
		Scope = code.Unset
 | 
						||
	}()
 | 
						||
 | 
						||
	// act
 | 
						||
	e := InvalidResourceState("field A", "Error description")
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.CatResource, e.Category())
 | 
						||
	assert.Equal(t, code.InvalidResourceState, e.Code())
 | 
						||
	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
	assert.EqualError(t, e, "invalid resource state: field A Error description")
 | 
						||
}
 | 
						||
 | 
						||
func TestInvalidResourceStateL_LogError(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	Scope = 99
 | 
						||
	defer func() { Scope = code.Unset }()
 | 
						||
	ctrl := gomock.NewController(t)
 | 
						||
	defer ctrl.Finish()
 | 
						||
 | 
						||
	l := logx.WithContext(context.Background())
 | 
						||
 | 
						||
	// act
 | 
						||
	e := InvalidResourceStateL(l, "field A", "Error description")
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.CatResource, e.Category())
 | 
						||
	assert.Equal(t, code.InvalidResourceState, e.Code())
 | 
						||
	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
	assert.EqualError(t, e, "invalid resource state: field A Error description")
 | 
						||
}
 | 
						||
 | 
						||
func TestAuthExpired_OK(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	Scope = 99
 | 
						||
	defer func() {
 | 
						||
		Scope = code.Unset
 | 
						||
	}()
 | 
						||
 | 
						||
	// act
 | 
						||
	e := AuthExpired("field A", "Error description")
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.CatAuth, e.Category())
 | 
						||
	assert.Equal(t, code.AuthExpired, e.Code())
 | 
						||
	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
	assert.Contains(t, e.Error(), "field A")
 | 
						||
	assert.Contains(t, e.Error(), "Error description")
 | 
						||
}
 | 
						||
 | 
						||
func TestUnauthorized_WithStrings_ShouldHasCatAuth_DetailCodeUnauthorized(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	Scope = 99
 | 
						||
	defer func() {
 | 
						||
		Scope = code.Unset
 | 
						||
	}()
 | 
						||
 | 
						||
	// act
 | 
						||
	e := Unauthorized("field A", "Error description")
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.CatAuth, e.Category())
 | 
						||
	assert.Equal(t, code.Unauthorized, e.Code())
 | 
						||
	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
	assert.Contains(t, e.Error(), "field A")
 | 
						||
	assert.Contains(t, e.Error(), "Error description")
 | 
						||
}
 | 
						||
 | 
						||
func TestInvalidPosixTime_WithStrings_ShouldHasCatAuth_DetailCodeInvalidPosixTime(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	Scope = 99
 | 
						||
	defer func() {
 | 
						||
		Scope = code.Unset
 | 
						||
	}()
 | 
						||
 | 
						||
	// act
 | 
						||
	e := InvalidPosixTime("field A", "Error description")
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.CatAuth, e.Category())
 | 
						||
	assert.Equal(t, code.InvalidPosixTime, e.Code())
 | 
						||
	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
	assert.Contains(t, e.Error(), "field A")
 | 
						||
	assert.Contains(t, e.Error(), "Error description")
 | 
						||
}
 | 
						||
 | 
						||
func TestSigAndPayloadNotMatched_WithStrings_ShouldHasCatAuth_DetailCodeSigAndPayloadNotMatched(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	Scope = 99
 | 
						||
	defer func() {
 | 
						||
		Scope = code.Unset
 | 
						||
	}()
 | 
						||
 | 
						||
	// act
 | 
						||
	e := SigAndPayloadNotMatched("field A", "Error description")
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.CatAuth, e.Category())
 | 
						||
	assert.Equal(t, code.SigAndPayloadNotMatched, e.Code())
 | 
						||
	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
	assert.Contains(t, e.Error(), "field A")
 | 
						||
	assert.Contains(t, e.Error(), "Error description")
 | 
						||
}
 | 
						||
 | 
						||
func TestForbidden_WithStrings_ShouldHasCatAuth_DetailCodeForbidden(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	Scope = 99
 | 
						||
	defer func() {
 | 
						||
		Scope = code.Unset
 | 
						||
	}()
 | 
						||
 | 
						||
	// act
 | 
						||
	e := Forbidden("field A", "Error description")
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.CatAuth, e.Category())
 | 
						||
	assert.Equal(t, code.Forbidden, e.Code())
 | 
						||
	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
	assert.Contains(t, e.Error(), "field A")
 | 
						||
	assert.Contains(t, e.Error(), "Error description")
 | 
						||
}
 | 
						||
 | 
						||
func TestXBCInternal_WithStrings_ShouldHasCatResource_DetailCodeXBCInternal(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	Scope = 99
 | 
						||
	defer func() {
 | 
						||
		Scope = code.Unset
 | 
						||
	}()
 | 
						||
 | 
						||
	// act
 | 
						||
	e := ArkInternal("field A", "Error description")
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.CatArk, e.Category())
 | 
						||
	assert.Equal(t, code.ArkInternal, e.Code())
 | 
						||
	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
	assert.Contains(t, e.Error(), "field A")
 | 
						||
	assert.Contains(t, e.Error(), "Error description")
 | 
						||
}
 | 
						||
 | 
						||
func TestGeneralInternalError_WithStrings_DetailInternalError(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	Scope = 99
 | 
						||
	defer func() {
 | 
						||
		Scope = code.Unset
 | 
						||
	}()
 | 
						||
 | 
						||
	// act
 | 
						||
	e := SystemInternalError("field A", "Error description")
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.CatSystem, e.Category())
 | 
						||
	assert.Equal(t, code.SystemInternalError, e.Code())
 | 
						||
	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
	assert.Contains(t, e.Error(), "field A")
 | 
						||
	assert.Contains(t, e.Error(), "Error description")
 | 
						||
}
 | 
						||
 | 
						||
func TestGeneralInternalErrorL_WithStrings_DetailInternalError(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	Scope = 99
 | 
						||
	defer func() { Scope = code.Unset }()
 | 
						||
	ctrl := gomock.NewController(t)
 | 
						||
	defer ctrl.Finish()
 | 
						||
 | 
						||
	l := logx.WithContext(context.Background())
 | 
						||
 | 
						||
	// act
 | 
						||
	e := SystemInternalErrorL(l, "field A", "Error description")
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.CatSystem, e.Category())
 | 
						||
	assert.Equal(t, code.SystemInternalError, e.Code())
 | 
						||
	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
	assert.Contains(t, e.Error(), "field A")
 | 
						||
	assert.Contains(t, e.Error(), "Error description")
 | 
						||
}
 | 
						||
 | 
						||
func TestSystemMaintainError_WithStrings_DetailSystemMaintainError(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	Scope = 99
 | 
						||
	defer func() { Scope = code.Unset }()
 | 
						||
	ctrl := gomock.NewController(t)
 | 
						||
	defer ctrl.Finish()
 | 
						||
 | 
						||
	l := logx.WithContext(context.Background())
 | 
						||
 | 
						||
	// act
 | 
						||
	e := SystemMaintainErrorL(l, "field A", "Error description")
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.CatSystem, e.Category())
 | 
						||
	assert.Equal(t, code.SystemMaintainError, e.Code())
 | 
						||
	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
	assert.Contains(t, e.Error(), "field A")
 | 
						||
	assert.Contains(t, e.Error(), "Error description")
 | 
						||
}
 | 
						||
 | 
						||
func TestResourceAlreadyExist_WithStrings_DetailInternalError(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	Scope = 99
 | 
						||
	defer func() {
 | 
						||
		Scope = code.Unset
 | 
						||
	}()
 | 
						||
 | 
						||
	// act
 | 
						||
	e := ResourceAlreadyExist("field A", "Error description")
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.CatResource, e.Category())
 | 
						||
	assert.Equal(t, code.ResourceAlreadyExist, e.Code())
 | 
						||
	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
	assert.Contains(t, e.Error(), "field A")
 | 
						||
	assert.Contains(t, e.Error(), "Error description")
 | 
						||
}
 | 
						||
 | 
						||
func TestResourceAlreadyExistL_WithStrings_DetailInternalError(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	Scope = 99
 | 
						||
	defer func() { Scope = code.Unset }()
 | 
						||
	ctrl := gomock.NewController(t)
 | 
						||
	defer ctrl.Finish()
 | 
						||
 | 
						||
	l := logx.WithContext(context.Background())
 | 
						||
 | 
						||
	// act
 | 
						||
	e := ResourceAlreadyExistL(l, "field A", "Error description")
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.CatResource, e.Category())
 | 
						||
	assert.Equal(t, code.ResourceAlreadyExist, e.Code())
 | 
						||
	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
	assert.Contains(t, e.Error(), "field A")
 | 
						||
	assert.Contains(t, e.Error(), "Error description")
 | 
						||
}
 | 
						||
 | 
						||
func TestResourceInsufficient_WithStrings_DetailInternalError(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	Scope = 99
 | 
						||
	defer func() {
 | 
						||
		Scope = code.Unset
 | 
						||
	}()
 | 
						||
 | 
						||
	// act
 | 
						||
	e := ResourceInsufficient("field A", "Error description")
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.CatResource, e.Category())
 | 
						||
	assert.Equal(t, code.ResourceInsufficient, e.Code())
 | 
						||
	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
	assert.Contains(t, e.Error(), "field A")
 | 
						||
	assert.Contains(t, e.Error(), "Error description")
 | 
						||
}
 | 
						||
 | 
						||
func TestResourceInsufficientL_WithStrings_DetailInternalError(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	Scope = 99
 | 
						||
	defer func() { Scope = code.Unset }()
 | 
						||
	ctrl := gomock.NewController(t)
 | 
						||
	defer ctrl.Finish()
 | 
						||
 | 
						||
	l := logx.WithContext(context.Background())
 | 
						||
 | 
						||
	// act
 | 
						||
	e := ResourceInsufficientL(l, "field A", "Error description")
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.CatResource, e.Category())
 | 
						||
	assert.Equal(t, code.ResourceInsufficient, e.Code())
 | 
						||
	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
	assert.Contains(t, e.Error(), "field A")
 | 
						||
	assert.Contains(t, e.Error(), "Error description")
 | 
						||
}
 | 
						||
 | 
						||
func TestInsufficientPermission_WithStrings_DetailInternalError(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	Scope = 99
 | 
						||
	defer func() {
 | 
						||
		Scope = code.Unset
 | 
						||
	}()
 | 
						||
 | 
						||
	// act
 | 
						||
	e := InsufficientPermission("field A", "Error description")
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.CatResource, e.Category())
 | 
						||
	assert.Equal(t, code.InsufficientPermission, e.Code())
 | 
						||
	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
	assert.Contains(t, e.Error(), "field A")
 | 
						||
	assert.Contains(t, e.Error(), "Error description")
 | 
						||
}
 | 
						||
 | 
						||
func TestInsufficientPermissionL_WithStrings_DetailInternalError(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	Scope = 99
 | 
						||
	defer func() { Scope = code.Unset }()
 | 
						||
	ctrl := gomock.NewController(t)
 | 
						||
	defer ctrl.Finish()
 | 
						||
 | 
						||
	l := logx.WithContext(context.Background())
 | 
						||
 | 
						||
	// act
 | 
						||
	e := InsufficientPermissionL(l, "field A", "Error description")
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.CatResource, e.Category())
 | 
						||
	assert.Equal(t, code.InsufficientPermission, e.Code())
 | 
						||
	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
	assert.Contains(t, e.Error(), "field A")
 | 
						||
	assert.Contains(t, e.Error(), "Error description")
 | 
						||
}
 | 
						||
 | 
						||
func TestInvalidMeasurementID_WithErrorStrings_ShouldReturnCorrectCodeAndErrorString(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	Scope = 99
 | 
						||
	defer func() {
 | 
						||
		Scope = code.Unset
 | 
						||
	}()
 | 
						||
 | 
						||
	// act
 | 
						||
	e := InvalidMeasurementID("field A", "Error description")
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.CatResource, e.Category())
 | 
						||
	assert.Equal(t, code.InvalidMeasurementID, e.Code())
 | 
						||
	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
	assert.Contains(t, e.Error(), "field A")
 | 
						||
	assert.Contains(t, e.Error(), "Error description")
 | 
						||
}
 | 
						||
 | 
						||
func TestInvalidMeasurementIDL_WithErrorStrings_ShouldReturnCorrectCodeAndErrorStringAndCallLogger(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	Scope = 99
 | 
						||
	defer func() { Scope = code.Unset }()
 | 
						||
	ctrl := gomock.NewController(t)
 | 
						||
	defer ctrl.Finish()
 | 
						||
 | 
						||
	l := logx.WithContext(context.Background())
 | 
						||
 | 
						||
	// act
 | 
						||
	e := InvalidMeasurementIDL(l, "field A", "Error description")
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.CatResource, e.Category())
 | 
						||
	assert.Equal(t, code.InvalidMeasurementID, e.Code())
 | 
						||
	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
	assert.Contains(t, e.Error(), "field A")
 | 
						||
	assert.Contains(t, e.Error(), "Error description")
 | 
						||
}
 | 
						||
 | 
						||
func TestResourceExpired_OK(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	Scope = 99
 | 
						||
	defer func() {
 | 
						||
		Scope = code.Unset
 | 
						||
	}()
 | 
						||
 | 
						||
	// act
 | 
						||
	e := ResourceExpired("field A", "Error description")
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.CatResource, e.Category())
 | 
						||
	assert.Equal(t, code.ResourceExpired, e.Code())
 | 
						||
	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
	assert.Contains(t, e.Error(), "field A")
 | 
						||
	assert.Contains(t, e.Error(), "Error description")
 | 
						||
}
 | 
						||
 | 
						||
func TestResourceExpiredL_LogError(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	Scope = 99
 | 
						||
	defer func() { Scope = code.Unset }()
 | 
						||
	ctrl := gomock.NewController(t)
 | 
						||
	defer ctrl.Finish()
 | 
						||
 | 
						||
	l := logx.WithContext(context.Background())
 | 
						||
 | 
						||
	// act
 | 
						||
	e := ResourceExpiredL(l, "field A", "Error description")
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.CatResource, e.Category())
 | 
						||
	assert.Equal(t, code.ResourceExpired, e.Code())
 | 
						||
	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
	assert.Contains(t, e.Error(), "field A")
 | 
						||
	assert.Contains(t, e.Error(), "Error description")
 | 
						||
}
 | 
						||
 | 
						||
func TestResourceMigrated_OK(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	Scope = 99
 | 
						||
	defer func() {
 | 
						||
		Scope = code.Unset
 | 
						||
	}()
 | 
						||
 | 
						||
	// act
 | 
						||
	e := ResourceMigrated("field A", "Error description")
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.CatResource, e.Category())
 | 
						||
	assert.Equal(t, code.ResourceMigrated, e.Code())
 | 
						||
	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
	assert.Contains(t, e.Error(), "field A")
 | 
						||
	assert.Contains(t, e.Error(), "Error description")
 | 
						||
}
 | 
						||
 | 
						||
func TestResourceMigratedL_LogError(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	Scope = 99
 | 
						||
	defer func() { Scope = code.Unset }()
 | 
						||
	ctrl := gomock.NewController(t)
 | 
						||
	defer ctrl.Finish()
 | 
						||
 | 
						||
	l := logx.WithContext(context.Background())
 | 
						||
 | 
						||
	// act
 | 
						||
	e := ResourceMigratedL(l, "field A", "Error description")
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.CatResource, e.Category())
 | 
						||
	assert.Equal(t, code.ResourceMigrated, e.Code())
 | 
						||
	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
	assert.Contains(t, e.Error(), "field A")
 | 
						||
	assert.Contains(t, e.Error(), "Error description")
 | 
						||
}
 | 
						||
 | 
						||
func TestInsufficientQuota_OK(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	Scope = 99
 | 
						||
	defer func() {
 | 
						||
		Scope = code.Unset
 | 
						||
	}()
 | 
						||
 | 
						||
	// act
 | 
						||
	e := InsufficientQuota("field A", "Error description")
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.CatResource, e.Category())
 | 
						||
	assert.Equal(t, code.InsufficientQuota, e.Code())
 | 
						||
	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
	assert.Contains(t, e.Error(), "field A")
 | 
						||
	assert.Contains(t, e.Error(), "Error description")
 | 
						||
}
 | 
						||
 | 
						||
func TestInsufficientQuotaL_LogError(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	Scope = 99
 | 
						||
	defer func() { Scope = code.Unset }()
 | 
						||
	ctrl := gomock.NewController(t)
 | 
						||
	defer ctrl.Finish()
 | 
						||
 | 
						||
	l := logx.WithContext(context.Background())
 | 
						||
 | 
						||
	// act
 | 
						||
	e := InsufficientQuotaL(l, "field A", "Error description")
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.CatResource, e.Category())
 | 
						||
	assert.Equal(t, code.InsufficientQuota, e.Code())
 | 
						||
	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
	assert.Contains(t, e.Error(), "field A")
 | 
						||
	assert.Contains(t, e.Error(), "Error description")
 | 
						||
}
 | 
						||
 | 
						||
func TestPublish_WithErrorStrings_ShouldReturnCorrectCodeAndErrorString(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	Scope = 99
 | 
						||
	defer func() {
 | 
						||
		Scope = code.Unset
 | 
						||
	}()
 | 
						||
 | 
						||
	// act
 | 
						||
	e := Publish("field A", "Error description")
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.CatPubSub, e.Category())
 | 
						||
	assert.Equal(t, code.Publish, e.Code())
 | 
						||
	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
	assert.Contains(t, e.Error(), "field A")
 | 
						||
	assert.Contains(t, e.Error(), "Error description")
 | 
						||
}
 | 
						||
 | 
						||
func TestPublishL_WithErrorStrings_ShouldReturnCorrectCodeAndErrorStringAndCallLogger(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	Scope = 99
 | 
						||
	defer func() { Scope = code.Unset }()
 | 
						||
	ctrl := gomock.NewController(t)
 | 
						||
	defer ctrl.Finish()
 | 
						||
 | 
						||
	l := logx.WithContext(context.Background())
 | 
						||
 | 
						||
	// act
 | 
						||
	e := PublishL(l, "field A", "Error description")
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.CatPubSub, e.Category())
 | 
						||
	assert.Equal(t, code.Publish, e.Code())
 | 
						||
	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
	assert.Contains(t, e.Error(), "field A")
 | 
						||
	assert.Contains(t, e.Error(), "Error description")
 | 
						||
}
 | 
						||
 | 
						||
func TestMsgSizeTooLarge_WithErrorStrings_ShouldReturnCorrectCodeAndErrorString(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	Scope = 99
 | 
						||
	defer func() {
 | 
						||
		Scope = code.Unset
 | 
						||
	}()
 | 
						||
 | 
						||
	// act
 | 
						||
	e := MsgSizeTooLarge("Error description")
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.CatPubSub, e.Category())
 | 
						||
	assert.Equal(t, code.MsgSizeTooLarge, e.Code())
 | 
						||
	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
	assert.Contains(t, e.Error(), "kafka error: Error description")
 | 
						||
}
 | 
						||
 | 
						||
func TestMsgSizeTooLargeL_WithErrorStrings_ShouldReturnCorrectCodeAndErrorStringAndCallLogger(t *testing.T) {
 | 
						||
	// setup
 | 
						||
	Scope = 99
 | 
						||
	defer func() { Scope = code.Unset }()
 | 
						||
	ctrl := gomock.NewController(t)
 | 
						||
	defer ctrl.Finish()
 | 
						||
 | 
						||
	l := logx.WithContext(context.Background())
 | 
						||
 | 
						||
	// act
 | 
						||
	e := MsgSizeTooLargeL(l, "Error description")
 | 
						||
 | 
						||
	// assert
 | 
						||
	assert.Equal(t, code.CatPubSub, e.Category())
 | 
						||
	assert.Equal(t, code.MsgSizeTooLarge, e.Code())
 | 
						||
	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
	assert.Contains(t, e.Error(), "kafka error: Error description")
 | 
						||
}
 | 
						||
 | 
						||
// func TestStructErr_WithInternalErr_ShouldIsFuncReportCorrectly(t *testing.T) {
 | 
						||
// 	// setup
 | 
						||
// 	Scope = 99
 | 
						||
// 	defer func() { Scope = code.Unset }()
 | 
						||
// 	// arrange 2 layers err
 | 
						||
// 	layer1Err := fmt.Errorf("layer 1 error")
 | 
						||
// 	layer2Err := fmt.Errorf("layer 2: %w", layer1Err)
 | 
						||
//
 | 
						||
// 	// act with error chain: InvalidFormat -> layer 2 err -> layer 1 err
 | 
						||
// 	e := InvalidFormat("field A", "Error description")
 | 
						||
// 	err := e.Wrap(layer2Err)
 | 
						||
// 	if err != nil {
 | 
						||
// 		t.Fatalf("Failed to wrap error: %v", err)
 | 
						||
// 	}
 | 
						||
//
 | 
						||
// 	// assert
 | 
						||
// 	assert.Equal(t, code.CatInput, e.Category())
 | 
						||
// 	assert.Equal(t, code.InvalidFormat, e.Code())
 | 
						||
// 	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
// 	assert.Contains(t, e.Error(), "field A")
 | 
						||
// 	assert.Contains(t, e.Error(), "Error description")
 | 
						||
//
 | 
						||
// 	// errors.Is should report correctly
 | 
						||
// 	assert.True(t, errors.Is(e, layer1Err))
 | 
						||
// 	assert.True(t, errors.Is(e, layer2Err))
 | 
						||
// }
 | 
						||
 | 
						||
// func TestStructErr_WithInternalErr_ShouldErrorOutputChainErrMessage(t *testing.T) {
 | 
						||
// 	// setup
 | 
						||
// 	Scope = 99
 | 
						||
// 	defer func() { Scope = code.Unset }()
 | 
						||
//
 | 
						||
// 	// arrange 2 layers err
 | 
						||
// 	layer1Err := fmt.Errorf("layer 1 error")
 | 
						||
// 	// act with error chain: InvalidFormat -> layer 1 err
 | 
						||
// 	e := InvalidFormat("field A", "Error description")
 | 
						||
// 	err := e.Wrap(layer1Err)
 | 
						||
// 	if err != nil {
 | 
						||
// 		t.Fatalf("Failed to wrap error: %v", err)
 | 
						||
// 	}
 | 
						||
//
 | 
						||
// 	// assert
 | 
						||
// 	assert.Equal(t, "invalid format: field A Error description: layer 1 error", e.Error())
 | 
						||
// }
 | 
						||
 | 
						||
// arrange a specific err type just for UT
 | 
						||
type testErr struct {
 | 
						||
	code int
 | 
						||
}
 | 
						||
 | 
						||
func (e *testErr) Error() string {
 | 
						||
	return strconv.Itoa(e.code)
 | 
						||
}
 | 
						||
 | 
						||
// func TestStructErr_WithInternalErr_ShouldAsFuncReportCorrectly(t *testing.T) {
 | 
						||
// 	// setup
 | 
						||
// 	Scope = 99
 | 
						||
// 	defer func() { Scope = code.Unset }()
 | 
						||
//
 | 
						||
// 	testE := &testErr{code: 123}
 | 
						||
// 	layer2Err := fmt.Errorf("layer 2: %w", testE)
 | 
						||
//
 | 
						||
// 	// act with error chain: InvalidFormat -> layer 2 err -> testErr
 | 
						||
// 	e := InvalidFormat("field A", "Error description")
 | 
						||
// 	err := e.Wrap(layer2Err)
 | 
						||
// 	if err != nil {
 | 
						||
// 		t.Fatalf("Failed to wrap error: %v", err)
 | 
						||
// 	}
 | 
						||
//
 | 
						||
// 	// assert
 | 
						||
// 	assert.Equal(t, code.CatInput, e.Category())
 | 
						||
// 	assert.Equal(t, code.InvalidFormat, e.Code())
 | 
						||
// 	assert.Equal(t, uint32(99), e.Scope())
 | 
						||
// 	assert.Contains(t, e.Error(), "field A")
 | 
						||
// 	assert.Contains(t, e.Error(), "Error description")
 | 
						||
//
 | 
						||
// 	// errors.As should report correctly
 | 
						||
// 	var internalErr *testErr
 | 
						||
// 	assert.True(t, errors.As(e, &internalErr))
 | 
						||
// 	assert.Equal(t, testE, internalErr)
 | 
						||
// }
 | 
						||
 | 
						||
/*
 | 
						||
benchmark run for 1 second:
 | 
						||
Benchmark_ErrorsIs_OneLayerError-4    	148281332	         8.68 ns/op	       0 B/op	       0 allocs/op
 | 
						||
Benchmark_ErrorsIs_TwoLayerError-4    	35048202	        32.4 ns/op	       0 B/op	       0 allocs/op
 | 
						||
Benchmark_ErrorsIs_FourLayerError-4   	15309349	        81.7 ns/op	       0 B/op	       0 allocs/op
 | 
						||
 | 
						||
Benchmark_ErrorsAs_OneLayerError-4    	16893205	        70.4 ns/op	       0 B/op	       0 allocs/op
 | 
						||
Benchmark_ErrorsAs_TwoLayerError-4    	10568083	       112 ns/op	       0 B/op	       0 allocs/op
 | 
						||
Benchmark_ErrorsAs_FourLayerError-4   	 6307729	       188 ns/op	       0 B/op	       0 allocs/op
 | 
						||
*/
 | 
						||
func Benchmark_ErrorsIs_OneLayerError(b *testing.B) {
 | 
						||
	layer1Err := &testErr{code: 123}
 | 
						||
	var err error = layer1Err
 | 
						||
 | 
						||
	b.ReportAllocs()
 | 
						||
	b.ResetTimer()
 | 
						||
	for i := 0; i < b.N; i++ {
 | 
						||
		errors.Is(err, layer1Err)
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
func Benchmark_ErrorsIs_TwoLayerError(b *testing.B) {
 | 
						||
	layer1Err := &testErr{code: 123}
 | 
						||
 | 
						||
	// act with error chain: InvalidFormat(layer 2) -> testErr(layer 1)
 | 
						||
	layer2Err := InvalidFormat("field A", "Error description")
 | 
						||
	err := layer2Err.Wrap(layer1Err)
 | 
						||
	if err != nil {
 | 
						||
		b.Fatalf("Failed to wrap error: %v", err)
 | 
						||
	}
 | 
						||
 | 
						||
	b.ReportAllocs()
 | 
						||
	b.ResetTimer()
 | 
						||
	for i := 0; i < b.N; i++ {
 | 
						||
		errors.Is(layer2Err, layer1Err)
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
func Benchmark_ErrorsIs_FourLayerError(b *testing.B) {
 | 
						||
	layer1Err := &testErr{code: 123}
 | 
						||
	layer2Err := fmt.Errorf("layer 2: %w", layer1Err)
 | 
						||
	layer3Err := fmt.Errorf("layer 3: %w", layer2Err)
 | 
						||
	// act with error chain: InvalidFormat(layer 4) -> Error(layer 3) -> Error(layer 2) -> testErr(layer 1)
 | 
						||
	layer4Err := InvalidFormat("field A", "Error description")
 | 
						||
	err := layer4Err.Wrap(layer3Err)
 | 
						||
	if err != nil {
 | 
						||
		b.Fatalf("Failed to wrap error: %v", err)
 | 
						||
	}
 | 
						||
 | 
						||
	b.ReportAllocs()
 | 
						||
	b.ResetTimer()
 | 
						||
	for i := 0; i < b.N; i++ {
 | 
						||
		errors.Is(layer4Err, layer1Err)
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
func Benchmark_ErrorsAs_OneLayerError(b *testing.B) {
 | 
						||
	layer1Err := &testErr{code: 123}
 | 
						||
	var err error = layer1Err
 | 
						||
 | 
						||
	b.ReportAllocs()
 | 
						||
	b.ResetTimer()
 | 
						||
	var internalErr *testErr
 | 
						||
	for i := 0; i < b.N; i++ {
 | 
						||
		errors.As(err, &internalErr)
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
func Benchmark_ErrorsAs_TwoLayerError(b *testing.B) {
 | 
						||
	layer1Err := &testErr{code: 123}
 | 
						||
 | 
						||
	// act with error chain: InvalidFormat(layer 2) -> testErr(layer 1)
 | 
						||
	layer2Err := InvalidFormat("field A", "Error description")
 | 
						||
	err := layer2Err.Wrap(layer1Err)
 | 
						||
	if err != nil {
 | 
						||
		b.Fatalf("Failed to wrap error: %v", err)
 | 
						||
	}
 | 
						||
 | 
						||
	b.ReportAllocs()
 | 
						||
	b.ResetTimer()
 | 
						||
	var internalErr *testErr
 | 
						||
	for i := 0; i < b.N; i++ {
 | 
						||
		errors.As(layer2Err, &internalErr)
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
func Benchmark_ErrorsAs_FourLayerError(b *testing.B) {
 | 
						||
	layer1Err := &testErr{code: 123}
 | 
						||
	layer2Err := fmt.Errorf("layer 2: %w", layer1Err)
 | 
						||
	layer3Err := fmt.Errorf("layer 3: %w", layer2Err)
 | 
						||
	// act with error chain: InvalidFormat(layer 4) -> Error(layer 3) -> Error(layer 2) -> testErr(layer 1)
 | 
						||
	layer4Err := InvalidFormat("field A", "Error description")
 | 
						||
	err := layer4Err.Wrap(layer3Err)
 | 
						||
	if err != nil {
 | 
						||
		b.Fatalf("Failed to wrap error: %v", err)
 | 
						||
	}
 | 
						||
 | 
						||
	b.ReportAllocs()
 | 
						||
	b.ResetTimer()
 | 
						||
	var internalErr *testErr
 | 
						||
	for i := 0; i < b.N; i++ {
 | 
						||
		errors.As(layer4Err, &internalErr)
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
func TestFromError(t *testing.T) {
 | 
						||
	tests := []struct {
 | 
						||
		name       string
 | 
						||
		givenError error
 | 
						||
		want       *LibError
 | 
						||
	}{
 | 
						||
		{
 | 
						||
			"given nil error should return nil",
 | 
						||
			nil,
 | 
						||
			nil,
 | 
						||
		},
 | 
						||
		{
 | 
						||
			"given normal error should return nil",
 | 
						||
			errors.New("normal error"),
 | 
						||
			nil,
 | 
						||
		},
 | 
						||
		{
 | 
						||
			"given Err should return Err",
 | 
						||
			ResourceNotFound("fake error"),
 | 
						||
			ResourceNotFound("fake error"),
 | 
						||
		},
 | 
						||
		{
 | 
						||
			"given error wraps Err should return Err",
 | 
						||
			fmt.Errorf("outter error wraps %w", ResourceNotFound("fake error")),
 | 
						||
			ResourceNotFound("fake error"),
 | 
						||
		},
 | 
						||
	}
 | 
						||
	for _, tt := range tests {
 | 
						||
		t.Run(tt.name, func(t *testing.T) {
 | 
						||
			if got := FromError(tt.givenError); !reflect.DeepEqual(got, tt.want) {
 | 
						||
				t.Errorf("FromError() = %v, want %v", got, tt.want)
 | 
						||
			}
 | 
						||
		})
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
func Test_newErr(t *testing.T) {
 | 
						||
	type args struct {
 | 
						||
		scope  uint32
 | 
						||
		detail uint32
 | 
						||
		msg    string
 | 
						||
	}
 | 
						||
	tests := []struct {
 | 
						||
		name string
 | 
						||
		args args
 | 
						||
	}{
 | 
						||
		{
 | 
						||
			name: "ok",
 | 
						||
			args: args{
 | 
						||
				scope:  code.CloudEPMember,
 | 
						||
				detail: code.InvalidFormat,
 | 
						||
				msg:    "gg88g88",
 | 
						||
			},
 | 
						||
		},
 | 
						||
	}
 | 
						||
	for _, tt := range tests {
 | 
						||
		t.Run(tt.name, func(t *testing.T) {
 | 
						||
			er := newErr(tt.args.scope, tt.args.detail, tt.args.msg)
 | 
						||
			// er.CodeStr() 會補滿6碼,業務邏輯要回應這個
 | 
						||
			// 105,060 前面兩位會乘一萬做計算,中間兩位乘100 來做計算最後用補的
 | 
						||
			fmt.Println(er.Scope(), er.Category(), er.Code(), er.FullCode(), er.CodeStr())
 | 
						||
			fmt.Println(er.Error()) // 建立十原始錯誤 -> 業務邏輯,給客人看 gg88g88
 | 
						||
			er2 := fmt.Errorf("test origin err")
 | 
						||
			er = er.Wrap(er2)       // 包裝錯誤
 | 
						||
			fmt.Println(er.Error()) // gg88g88: test origin err
 | 
						||
			err := er.Unwrap()
 | 
						||
			if err != nil {
 | 
						||
				return
 | 
						||
			}
 | 
						||
		})
 | 
						||
	}
 | 
						||
}
 |