116 lines
3.6 KiB
Go
116 lines
3.6 KiB
Go
package errs
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"testing"
|
|
|
|
"backend/pkg/library/errors/code"
|
|
"google.golang.org/grpc/codes"
|
|
"google.golang.org/grpc/status"
|
|
)
|
|
|
|
func TestNewBuiltinGRPCErr(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
scope uint32
|
|
detail uint32
|
|
msg string
|
|
wantCat uint32
|
|
wantScope uint32
|
|
wantDet uint32
|
|
wantMsg string
|
|
}{
|
|
{"basic", 10, 3, "test", uint32(code.CatGRPC), 10, 3, "test"},
|
|
{"zero", 0, 0, "", uint32(code.CatGRPC), 0, 0, ""},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
e := newBuiltinGRPCErr(tt.scope, tt.detail, tt.msg)
|
|
if e.Category() != tt.wantCat || e.Scope() != tt.wantScope || e.Detail() != tt.wantDet || e.Error() != tt.wantMsg {
|
|
t.Errorf("newBuiltinGRPCErr = cat=%d scope=%d det=%d msg=%q, want %d %d %d %q",
|
|
e.Category(), e.Scope(), e.Detail(), e.Error(), tt.wantCat, tt.wantScope, tt.wantDet, tt.wantMsg)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestFromError(t *testing.T) {
|
|
base := New(10, uint32(code.DBError), 0, "base")
|
|
// but actually use fmt.Errorf("%w", base) for proper wrapping
|
|
tests := []struct {
|
|
name string
|
|
in error
|
|
want *Error
|
|
}{
|
|
{"nil", nil, nil},
|
|
{"not Error", errors.New("std"), nil},
|
|
{"direct Error", base, base},
|
|
{"wrapped Error", fmt.Errorf("wrap: %w", base), base},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := FromError(tt.in)
|
|
if (got == nil) != (tt.want == nil) {
|
|
t.Errorf("FromError = %v, want nil=%v", got, tt.want == nil)
|
|
}
|
|
if got != nil && (got.Category() != tt.want.Category() || got.Detail() != tt.want.Detail()) {
|
|
t.Errorf("FromError = cat=%d det=%d, want %d %d", got.Category(), got.Detail(), tt.want.Category(), tt.want.Detail())
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestFromCode(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
code uint32
|
|
wantScope uint32
|
|
wantCat uint32
|
|
wantDet uint32
|
|
}{
|
|
{"basic", 10201123, 10, 201, 123},
|
|
{"zero", 0, 0, 0, 0},
|
|
{"max", 99999999, 99, 999, 999},
|
|
{"overflow code", 100000000, 100, 0, 0}, // Parses as scope=100, but uint32 limits
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
e := FromCode(tt.code)
|
|
if e.Scope() != tt.wantScope || e.Category() != tt.wantCat || e.Detail() != tt.wantDet {
|
|
t.Errorf("FromCode = scope=%d cat=%d det=%d, want %d %d %d", e.Scope(), e.Category(), e.Detail(), tt.wantScope, tt.wantCat, tt.wantDet)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestFromGRPCError(t *testing.T) {
|
|
Scope = code.Gateway
|
|
tests := []struct {
|
|
name string
|
|
in error
|
|
wantScope uint32
|
|
wantCat uint32
|
|
wantDet uint32
|
|
wantMsg string
|
|
}{
|
|
{"nil", nil, 0, 0, 0, ""},
|
|
{"builtin OK", status.New(codes.OK, "").Err(), 0, 0, 0, ""},
|
|
{"builtin InvalidArgument", status.New(codes.InvalidArgument, "bad").Err(), uint32(code.Gateway), uint32(code.CatGRPC), uint32(codes.InvalidArgument), "bad"},
|
|
{"custom code", status.New(codes.Code(10201123), "custom").Err(), 10, 201, 123, "custom"},
|
|
{"unset scope with builtin", status.New(codes.NotFound, "not found").Err(), uint32(code.Gateway), uint32(code.CatGRPC), uint32(codes.NotFound), "not found"},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
e := FromGRPCError(tt.in)
|
|
if e == nil && (tt.wantScope != 0 || tt.wantCat != 0 || tt.wantDet != 0) {
|
|
t.Errorf("got nil, want non-nil")
|
|
}
|
|
if e != nil && (e.Scope() != tt.wantScope || e.Category() != tt.wantCat || e.Detail() != tt.wantDet || e.Error() != tt.wantMsg) {
|
|
t.Errorf("FromGRPCError = scope=%d cat=%d det=%d msg=%q, want %d %d %d %q",
|
|
e.Scope(), e.Category(), e.Detail(), e.Error(), tt.wantScope, tt.wantCat, tt.wantDet, tt.wantMsg)
|
|
}
|
|
})
|
|
}
|
|
}
|