Compare commits
No commits in common. "26a14a8a9cdc27520d63b83ebd87ef9fb64cb78a" and "ab72418c29602f4c228f1c5b2263be728b047ab4" have entirely different histories.
26a14a8a9c
...
ab72418c29
140
.golangci.yaml
140
.golangci.yaml
|
@ -1,140 +0,0 @@
|
||||||
run:
|
|
||||||
timeout: 3m
|
|
||||||
# Exit code when at least one issue was found.
|
|
||||||
# Default: 1
|
|
||||||
issues-exit-code: 2
|
|
||||||
# Include test files or not.
|
|
||||||
# Default: true
|
|
||||||
tests: false
|
|
||||||
|
|
||||||
# Reference URL: https://golangci-lint.run/usage/linters/
|
|
||||||
linters:
|
|
||||||
# Disable everything by default so upgrades to not include new - default
|
|
||||||
# enabled- linters.
|
|
||||||
disable-all: true
|
|
||||||
# Specifically enable linters we want to use.
|
|
||||||
enable:
|
|
||||||
# - depguard
|
|
||||||
- errcheck
|
|
||||||
# - godot
|
|
||||||
- gofmt
|
|
||||||
- goimports
|
|
||||||
- gosimple
|
|
||||||
- govet
|
|
||||||
- ineffassign
|
|
||||||
- misspell
|
|
||||||
- revive
|
|
||||||
# - staticcheck
|
|
||||||
- typecheck
|
|
||||||
- unused
|
|
||||||
# - wsl
|
|
||||||
- asasalint
|
|
||||||
- asciicheck
|
|
||||||
- bidichk
|
|
||||||
- bodyclose
|
|
||||||
# - containedctx
|
|
||||||
- contextcheck
|
|
||||||
# - cyclop
|
|
||||||
# - varnamelen
|
|
||||||
# - gci
|
|
||||||
- wastedassign
|
|
||||||
- whitespace
|
|
||||||
# - wrapcheck
|
|
||||||
- thelper
|
|
||||||
- tparallel
|
|
||||||
- unconvert
|
|
||||||
- unparam
|
|
||||||
- usestdlibvars
|
|
||||||
- tenv
|
|
||||||
- testableexamples
|
|
||||||
- stylecheck
|
|
||||||
- sqlclosecheck
|
|
||||||
- nosprintfhostport
|
|
||||||
- paralleltest
|
|
||||||
- prealloc
|
|
||||||
- predeclared
|
|
||||||
- promlinter
|
|
||||||
- reassign
|
|
||||||
- rowserrcheck
|
|
||||||
- nakedret
|
|
||||||
- nestif
|
|
||||||
- nilerr
|
|
||||||
- nilnil
|
|
||||||
- nlreturn
|
|
||||||
- noctx
|
|
||||||
- nolintlint
|
|
||||||
- nonamedreturns
|
|
||||||
- decorder
|
|
||||||
- dogsled
|
|
||||||
# - dupl
|
|
||||||
- dupword
|
|
||||||
- durationcheck
|
|
||||||
- errchkjson
|
|
||||||
- errname
|
|
||||||
- errorlint
|
|
||||||
# - execinquery
|
|
||||||
- exhaustive
|
|
||||||
- exportloopref
|
|
||||||
- forbidigo
|
|
||||||
- forcetypeassert
|
|
||||||
# - gochecknoglobals
|
|
||||||
- gochecknoinits
|
|
||||||
- gocognit
|
|
||||||
- goconst
|
|
||||||
- gocritic
|
|
||||||
- gocyclo
|
|
||||||
# - godox
|
|
||||||
# - goerr113
|
|
||||||
# - gofumpt
|
|
||||||
- goheader
|
|
||||||
- gomoddirectives
|
|
||||||
# - gomodguard always failed
|
|
||||||
- goprintffuncname
|
|
||||||
- gosec
|
|
||||||
- grouper
|
|
||||||
- importas
|
|
||||||
- interfacebloat
|
|
||||||
# - ireturn
|
|
||||||
- lll
|
|
||||||
- loggercheck
|
|
||||||
- maintidx
|
|
||||||
- makezero
|
|
||||||
|
|
||||||
issues:
|
|
||||||
exclude-rules:
|
|
||||||
- path: _test\.go
|
|
||||||
linters:
|
|
||||||
- funlen
|
|
||||||
- goconst
|
|
||||||
- interfacer
|
|
||||||
- dupl
|
|
||||||
- lll
|
|
||||||
- goerr113
|
|
||||||
- errcheck
|
|
||||||
- gocritic
|
|
||||||
- cyclop
|
|
||||||
- wrapcheck
|
|
||||||
- gocognit
|
|
||||||
- contextcheck
|
|
||||||
|
|
||||||
linters-settings:
|
|
||||||
gci:
|
|
||||||
sections:
|
|
||||||
- standard # Standard section: captures all standard packages.
|
|
||||||
- default # Default section: contains all imports that could not be matched to another section type.
|
|
||||||
gocognit:
|
|
||||||
# Minimal code complexity to report.
|
|
||||||
# Default: 30 (but we recommend 10-20)
|
|
||||||
min-complexity: 40
|
|
||||||
nestif:
|
|
||||||
# Minimal complexity of if statements to report.
|
|
||||||
# Default: 5
|
|
||||||
min-complexity: 10
|
|
||||||
lll:
|
|
||||||
# Max line length, lines longer will be reported.
|
|
||||||
# '\t' is counted as 1 character by default, and can be changed with the tab-width option.
|
|
||||||
# Default: 120.
|
|
||||||
line-length: 200
|
|
||||||
# Tab width in spaces.
|
|
||||||
# Default: 1
|
|
||||||
tab-width: 1
|
|
9
Makefile
9
Makefile
|
@ -1,9 +0,0 @@
|
||||||
.PHONY: test
|
|
||||||
test: # 進行測試
|
|
||||||
go test -v --cover ./...
|
|
||||||
|
|
||||||
.PHONY: fmt
|
|
||||||
fmt: # 格式優化
|
|
||||||
$(GOFMT) -w $(GOFILES)
|
|
||||||
goimports -w ./
|
|
||||||
|
|
|
@ -95,5 +95,5 @@ const (
|
||||||
const (
|
const (
|
||||||
_ = iota + CatArk
|
_ = iota + CatArk
|
||||||
ArkInternal
|
ArkInternal
|
||||||
ArkHTTP400
|
ArkHttp400
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,21 +1,20 @@
|
||||||
package errors
|
package error
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"code.30cm.net/digimon/library-go/errors/code"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"code.30cm.net/digimon/library-go/errors/code"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
_ "github.com/zeromicro/go-zero/core/logx"
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newErr(scope, detail uint32, msg string) *LibError {
|
func newErr(scope, detail uint32, msg string) *Err {
|
||||||
cat := detail / 100 * 100
|
cat := detail / 100 * 100
|
||||||
|
return &Err{
|
||||||
return &LibError{
|
|
||||||
category: cat,
|
category: cat,
|
||||||
code: detail,
|
code: detail,
|
||||||
scope: scope,
|
scope: scope,
|
||||||
|
@ -23,8 +22,8 @@ func newErr(scope, detail uint32, msg string) *LibError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newBuiltinGRPCErr(scope, detail uint32, msg string) *LibError {
|
func newBuiltinGRPCErr(scope, detail uint32, msg string) *Err {
|
||||||
return &LibError{
|
return &Err{
|
||||||
category: code.CatGRPC,
|
category: code.CatGRPC,
|
||||||
code: detail,
|
code: detail,
|
||||||
scope: scope,
|
scope: scope,
|
||||||
|
@ -35,12 +34,12 @@ func newBuiltinGRPCErr(scope, detail uint32, msg string) *LibError {
|
||||||
// FromError tries to let error as Err
|
// FromError tries to let error as Err
|
||||||
// it supports to unwrap error that has Err
|
// it supports to unwrap error that has Err
|
||||||
// return nil if failed to transfer
|
// return nil if failed to transfer
|
||||||
func FromError(err error) *LibError {
|
func FromError(err error) *Err {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var e *LibError
|
var e *Err
|
||||||
if errors.As(err, &e) {
|
if errors.As(err, &e) {
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
@ -53,11 +52,10 @@ func FromError(err error) *LibError {
|
||||||
// 12 represents Scope
|
// 12 represents Scope
|
||||||
// 03 represents Category
|
// 03 represents Category
|
||||||
// 14 represents Detail error code
|
// 14 represents Detail error code
|
||||||
func FromCode(code uint32) *LibError {
|
func FromCode(code uint32) *Err {
|
||||||
scope := code / 10000
|
scope := code / 10000
|
||||||
detail := code % 10000
|
detail := code % 10000
|
||||||
|
return &Err{
|
||||||
return &LibError{
|
|
||||||
category: detail / 100 * 100,
|
category: detail / 100 * 100,
|
||||||
code: detail,
|
code: detail,
|
||||||
scope: scope,
|
scope: scope,
|
||||||
|
@ -67,7 +65,7 @@ func FromCode(code uint32) *LibError {
|
||||||
|
|
||||||
// FromGRPCError transfer error to Err
|
// FromGRPCError transfer error to Err
|
||||||
// useful for gRPC client
|
// useful for gRPC client
|
||||||
func FromGRPCError(err error) *LibError {
|
func FromGRPCError(err error) *Err {
|
||||||
s, _ := status.FromError(err)
|
s, _ := status.FromError(err)
|
||||||
e := FromCode(uint32(s.Code()))
|
e := FromCode(uint32(s.Code()))
|
||||||
e.msg = s.Message()
|
e.msg = s.Message()
|
||||||
|
@ -83,335 +81,311 @@ func FromGRPCError(err error) *LibError {
|
||||||
// Deprecated: check GRPCStatus() in Errs struct
|
// Deprecated: check GRPCStatus() in Errs struct
|
||||||
// ToGRPCError returns the status.Status
|
// ToGRPCError returns the status.Status
|
||||||
// Useful to return error in gRPC server
|
// Useful to return error in gRPC server
|
||||||
func ToGRPCError(e *LibError) error {
|
func ToGRPCError(e *Err) error {
|
||||||
return status.New(codes.Code(e.FullCode()), e.Error()).Err()
|
return status.New(codes.Code(e.FullCode()), e.Error()).Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** System ***/
|
/*** System ***/
|
||||||
|
|
||||||
// SystemTimeoutError returns Err
|
// SystemTimeoutError returns Err
|
||||||
func SystemTimeoutError(s ...string) *LibError {
|
func SystemTimeoutError(s ...string) *Err {
|
||||||
return newErr(Scope, code.SystemTimeoutError, fmt.Sprintf("system timeout: %s", strings.Join(s, " ")))
|
return newErr(Scope, code.SystemTimeoutError, fmt.Sprintf("system timeout: %s", strings.Join(s, " ")))
|
||||||
}
|
}
|
||||||
|
|
||||||
// SystemTimeoutErrorL logs error message and returns Err
|
// SystemTimeoutErrorL logs error message and returns Err
|
||||||
func SystemTimeoutErrorL(l logx.Logger, s ...string) *LibError {
|
func SystemTimeoutErrorL(l logx.Logger, s ...string) *Err {
|
||||||
e := SystemTimeoutError(s...)
|
e := SystemTimeoutError(s...)
|
||||||
l.WithCallerSkip(1).Error(e.Error())
|
l.WithCallerSkip(1).Error(e.Error())
|
||||||
|
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
// SystemInternalError returns Err struct
|
// SystemInternalError returns Err struct
|
||||||
func SystemInternalError(s ...string) *LibError {
|
func SystemInternalError(s ...string) *Err {
|
||||||
return newErr(Scope, code.SystemInternalError, fmt.Sprintf("internal error: %s", strings.Join(s, " ")))
|
return newErr(Scope, code.SystemInternalError, fmt.Sprintf("internal error: %s", strings.Join(s, " ")))
|
||||||
}
|
}
|
||||||
|
|
||||||
// SystemInternalErrorL logs error message and returns Err
|
// SystemInternalErrorL logs error message and returns Err
|
||||||
func SystemInternalErrorL(l logx.Logger, s ...string) *LibError {
|
func SystemInternalErrorL(l logx.Logger, s ...string) *Err {
|
||||||
e := SystemInternalError(s...)
|
e := SystemInternalError(s...)
|
||||||
l.WithCallerSkip(1).Error(e.Error())
|
l.WithCallerSkip(1).Error(e.Error())
|
||||||
|
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
// SystemMaintainErrorL logs error message and returns Err
|
// SystemMaintainErrorL logs error message and returns Err
|
||||||
func SystemMaintainErrorL(l logx.Logger, s ...string) *LibError {
|
func SystemMaintainErrorL(l logx.Logger, s ...string) *Err {
|
||||||
e := SystemMaintainError(s...)
|
e := SystemMaintainError(s...)
|
||||||
l.WithCallerSkip(1).Error(e.Error())
|
l.WithCallerSkip(1).Error(e.Error())
|
||||||
|
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
// SystemMaintainError returns Err struct
|
// SystemMaintainError returns Err struct
|
||||||
func SystemMaintainError(s ...string) *LibError {
|
func SystemMaintainError(s ...string) *Err {
|
||||||
return newErr(Scope, code.SystemMaintainError, fmt.Sprintf("service under maintenance: %s", strings.Join(s, " ")))
|
return newErr(Scope, code.SystemMaintainError, fmt.Sprintf("service under maintenance: %s", strings.Join(s, " ")))
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** CatInput ***/
|
/*** CatInput ***/
|
||||||
|
|
||||||
// InvalidFormat returns Err struct
|
// InvalidFormat returns Err struct
|
||||||
func InvalidFormat(s ...string) *LibError {
|
func InvalidFormat(s ...string) *Err {
|
||||||
return newErr(Scope, code.InvalidFormat, fmt.Sprintf("invalid format: %s", strings.Join(s, " ")))
|
return newErr(Scope, code.InvalidFormat, fmt.Sprintf("invalid format: %s", strings.Join(s, " ")))
|
||||||
}
|
}
|
||||||
|
|
||||||
// InvalidFormatL logs error message and returns Err
|
// InvalidFormatL logs error message and returns Err
|
||||||
func InvalidFormatL(l logx.Logger, s ...string) *LibError {
|
func InvalidFormatL(l logx.Logger, s ...string) *Err {
|
||||||
e := InvalidFormat(s...)
|
e := InvalidFormat(s...)
|
||||||
l.WithCallerSkip(1).Error(e.Error())
|
l.WithCallerSkip(1).Error(e.Error())
|
||||||
|
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
// InvalidRange returns Err struct
|
// InvalidRange returns Err struct
|
||||||
func InvalidRange(s ...string) *LibError {
|
func InvalidRange(s ...string) *Err {
|
||||||
return newErr(Scope, code.InvalidRange, fmt.Sprintf("invalid range: %s", strings.Join(s, " ")))
|
return newErr(Scope, code.InvalidRange, fmt.Sprintf("invalid range: %s", strings.Join(s, " ")))
|
||||||
}
|
}
|
||||||
|
|
||||||
// InvalidRangeL logs error message and returns Err
|
// InvalidRangeL logs error message and returns Err
|
||||||
func InvalidRangeL(l logx.Logger, s ...string) *LibError {
|
func InvalidRangeL(l logx.Logger, s ...string) *Err {
|
||||||
e := InvalidRange(s...)
|
e := InvalidRange(s...)
|
||||||
l.WithCallerSkip(1).Error(e.Error())
|
l.WithCallerSkip(1).Error(e.Error())
|
||||||
|
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
// NotValidImplementation returns Err struct
|
// NotValidImplementation returns Err struct
|
||||||
func NotValidImplementation(s ...string) *LibError {
|
func NotValidImplementation(s ...string) *Err {
|
||||||
return newErr(Scope, code.NotValidImplementation, fmt.Sprintf("not valid implementation: %s", strings.Join(s, " ")))
|
return newErr(Scope, code.NotValidImplementation, fmt.Sprintf("not valid implementation: %s", strings.Join(s, " ")))
|
||||||
}
|
}
|
||||||
|
|
||||||
// NotValidImplementationL logs error message and returns Err
|
// NotValidImplementationL logs error message and returns Err
|
||||||
func NotValidImplementationL(l logx.Logger, s ...string) *LibError {
|
func NotValidImplementationL(l logx.Logger, s ...string) *Err {
|
||||||
e := NotValidImplementation(s...)
|
e := NotValidImplementation(s...)
|
||||||
l.WithCallerSkip(1).Error(e.Error())
|
l.WithCallerSkip(1).Error(e.Error())
|
||||||
|
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** CatDB ***/
|
/*** CatDB ***/
|
||||||
|
|
||||||
// DBError returns Err
|
// DBError returns Err
|
||||||
func DBError(s ...string) *LibError {
|
func DBError(s ...string) *Err {
|
||||||
return newErr(Scope, code.DBError, fmt.Sprintf("db error: %s", strings.Join(s, " ")))
|
return newErr(Scope, code.DBError, fmt.Sprintf("db error: %s", strings.Join(s, " ")))
|
||||||
}
|
}
|
||||||
|
|
||||||
// DBErrorL logs error message and returns Err
|
// DBErrorL logs error message and returns Err
|
||||||
func DBErrorL(l logx.Logger, s ...string) *LibError {
|
func DBErrorL(l logx.Logger, s ...string) *Err {
|
||||||
e := DBError(s...)
|
e := DBError(s...)
|
||||||
l.WithCallerSkip(1).Error(e.Error())
|
l.WithCallerSkip(1).Error(e.Error())
|
||||||
|
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
// DBDataConvert returns Err
|
// DBDataConvert returns Err
|
||||||
func DBDataConvert(s ...string) *LibError {
|
func DBDataConvert(s ...string) *Err {
|
||||||
return newErr(Scope, code.DBDataConvert, fmt.Sprintf("data from db convert error: %s", strings.Join(s, " ")))
|
return newErr(Scope, code.DBDataConvert, fmt.Sprintf("data from db convert error: %s", strings.Join(s, " ")))
|
||||||
}
|
}
|
||||||
|
|
||||||
// DBDataConvertL logs error message and returns Err
|
// DBDataConvertL logs error message and returns Err
|
||||||
func DBDataConvertL(l logx.Logger, s ...string) *LibError {
|
func DBDataConvertL(l logx.Logger, s ...string) *Err {
|
||||||
e := DBDataConvert(s...)
|
e := DBDataConvert(s...)
|
||||||
l.WithCallerSkip(1).Error(e.Error())
|
l.WithCallerSkip(1).Error(e.Error())
|
||||||
|
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
// DBDuplicate returns Err
|
// DBDuplicate returns Err
|
||||||
func DBDuplicate(s ...string) *LibError {
|
func DBDuplicate(s ...string) *Err {
|
||||||
return newErr(Scope, code.DBDuplicate, fmt.Sprintf("data Duplicate key error: %s", strings.Join(s, " ")))
|
return newErr(Scope, code.DBDuplicate, fmt.Sprintf("data Duplicate key error: %s", strings.Join(s, " ")))
|
||||||
}
|
}
|
||||||
|
|
||||||
// DBDuplicateL logs error message and returns Err
|
// DBDuplicateL logs error message and returns Err
|
||||||
func DBDuplicateL(l logx.Logger, s ...string) *LibError {
|
func DBDuplicateL(l logx.Logger, s ...string) *Err {
|
||||||
e := DBDuplicate(s...)
|
e := DBDuplicate(s...)
|
||||||
l.WithCallerSkip(1).Error(e.Error())
|
l.WithCallerSkip(1).Error(e.Error())
|
||||||
|
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** CatResource ***/
|
/*** CatResource ***/
|
||||||
|
|
||||||
// ResourceNotFound returns Err and logging
|
// ResourceNotFound returns Err and logging
|
||||||
func ResourceNotFound(s ...string) *LibError {
|
func ResourceNotFound(s ...string) *Err {
|
||||||
return newErr(Scope, code.ResourceNotFound, fmt.Sprintf("resource not found: %s", strings.Join(s, " ")))
|
return newErr(Scope, code.ResourceNotFound, fmt.Sprintf("resource not found: %s", strings.Join(s, " ")))
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResourceNotFoundL logs error message and returns Err
|
// ResourceNotFoundL logs error message and returns Err
|
||||||
func ResourceNotFoundL(l logx.Logger, s ...string) *LibError {
|
func ResourceNotFoundL(l logx.Logger, s ...string) *Err {
|
||||||
e := ResourceNotFound(s...)
|
e := ResourceNotFound(s...)
|
||||||
l.WithCallerSkip(1).Error(e.Error())
|
l.WithCallerSkip(1).Error(e.Error())
|
||||||
|
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
// InvalidResourceFormat returns Err
|
// InvalidResourceFormat returns Err
|
||||||
func InvalidResourceFormat(s ...string) *LibError {
|
func InvalidResourceFormat(s ...string) *Err {
|
||||||
return newErr(Scope, code.InvalidResourceFormat, fmt.Sprintf("invalid resource format: %s", strings.Join(s, " ")))
|
return newErr(Scope, code.InvalidResourceFormat, fmt.Sprintf("invalid resource format: %s", strings.Join(s, " ")))
|
||||||
}
|
}
|
||||||
|
|
||||||
// InvalidResourceFormatL logs error message and returns Err
|
// InvalidResourceFormatL logs error message and returns Err
|
||||||
func InvalidResourceFormatL(l logx.Logger, s ...string) *LibError {
|
func InvalidResourceFormatL(l logx.Logger, s ...string) *Err {
|
||||||
e := InvalidResourceFormat(s...)
|
e := InvalidResourceFormat(s...)
|
||||||
l.WithCallerSkip(1).Error(e.Error())
|
l.WithCallerSkip(1).Error(e.Error())
|
||||||
|
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
// InvalidResourceState returns status not correct.
|
// InvalidResourceState returns status not correct.
|
||||||
// for example: company should be destroy, agent should be no-sensor/fail-install ...
|
// for example: company should be destroy, agent should be no-sensor/fail-install ...
|
||||||
func InvalidResourceState(s ...string) *LibError {
|
func InvalidResourceState(s ...string) *Err {
|
||||||
return newErr(Scope, code.InvalidResourceState, fmt.Sprintf("invalid resource state: %s", strings.Join(s, " ")))
|
return newErr(Scope, code.InvalidResourceState, fmt.Sprintf("invalid resource state: %s", strings.Join(s, " ")))
|
||||||
}
|
}
|
||||||
|
|
||||||
// InvalidResourceStateL logs error message and returns status not correct.
|
// InvalidResourceStateL logs error message and returns status not correct.
|
||||||
func InvalidResourceStateL(l logx.Logger, s ...string) *LibError {
|
func InvalidResourceStateL(l logx.Logger, s ...string) *Err {
|
||||||
e := InvalidResourceState(s...)
|
e := InvalidResourceState(s...)
|
||||||
l.WithCallerSkip(1).Error(e.Error())
|
l.WithCallerSkip(1).Error(e.Error())
|
||||||
|
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
func ResourceInsufficient(s ...string) *LibError {
|
func ResourceInsufficient(s ...string) *Err {
|
||||||
return newErr(Scope, code.ResourceInsufficient,
|
return newErr(Scope, code.ResourceInsufficient,
|
||||||
fmt.Sprintf("insufficient resource: %s", strings.Join(s, " ")))
|
fmt.Sprintf("insufficient resource: %s", strings.Join(s, " ")))
|
||||||
}
|
}
|
||||||
|
|
||||||
func ResourceInsufficientL(l logx.Logger, s ...string) *LibError {
|
func ResourceInsufficientL(l logx.Logger, s ...string) *Err {
|
||||||
e := ResourceInsufficient(s...)
|
e := ResourceInsufficient(s...)
|
||||||
l.WithCallerSkip(1).Error(e.Error())
|
l.WithCallerSkip(1).Error(e.Error())
|
||||||
|
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
// InsufficientPermission returns Err
|
// InsufficientPermission returns Err
|
||||||
func InsufficientPermission(s ...string) *LibError {
|
func InsufficientPermission(s ...string) *Err {
|
||||||
return newErr(Scope, code.InsufficientPermission,
|
return newErr(Scope, code.InsufficientPermission,
|
||||||
fmt.Sprintf("insufficient permission: %s", strings.Join(s, " ")))
|
fmt.Sprintf("insufficient permission: %s", strings.Join(s, " ")))
|
||||||
}
|
}
|
||||||
|
|
||||||
// InsufficientPermissionL returns Err and log
|
// InsufficientPermissionL returns Err and log
|
||||||
func InsufficientPermissionL(l logx.Logger, s ...string) *LibError {
|
func InsufficientPermissionL(l logx.Logger, s ...string) *Err {
|
||||||
e := InsufficientPermission(s...)
|
e := InsufficientPermission(s...)
|
||||||
l.WithCallerSkip(1).Error(e.Error())
|
l.WithCallerSkip(1).Error(e.Error())
|
||||||
|
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResourceAlreadyExist returns Err
|
// ResourceAlreadyExist returns Err
|
||||||
func ResourceAlreadyExist(s ...string) *LibError {
|
func ResourceAlreadyExist(s ...string) *Err {
|
||||||
return newErr(Scope, code.ResourceAlreadyExist, fmt.Sprintf("resource already exist: %s", strings.Join(s, " ")))
|
return newErr(Scope, code.ResourceAlreadyExist, fmt.Sprintf("resource already exist: %s", strings.Join(s, " ")))
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResourceAlreadyExistL logs error message and returns Err
|
// ResourceAlreadyExistL logs error message and returns Err
|
||||||
func ResourceAlreadyExistL(l logx.Logger, s ...string) *LibError {
|
func ResourceAlreadyExistL(l logx.Logger, s ...string) *Err {
|
||||||
e := ResourceAlreadyExist(s...)
|
e := ResourceAlreadyExist(s...)
|
||||||
l.WithCallerSkip(1).Error(e.Error())
|
l.WithCallerSkip(1).Error(e.Error())
|
||||||
|
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
// InvalidMeasurementID returns Err
|
// InvalidMeasurementID returns Err
|
||||||
func InvalidMeasurementID(s ...string) *LibError {
|
func InvalidMeasurementID(s ...string) *Err {
|
||||||
return newErr(Scope, code.InvalidMeasurementID, fmt.Sprintf("missing measurement id: %s", strings.Join(s, " ")))
|
return newErr(Scope, code.InvalidMeasurementID, fmt.Sprintf("missing measurement id: %s", strings.Join(s, " ")))
|
||||||
}
|
}
|
||||||
|
|
||||||
// InvalidMeasurementIDL logs error message and returns Err
|
// InvalidMeasurementIDL logs error message and returns Err
|
||||||
func InvalidMeasurementIDL(l logx.Logger, s ...string) *LibError {
|
func InvalidMeasurementIDL(l logx.Logger, s ...string) *Err {
|
||||||
e := InvalidMeasurementID(s...)
|
e := InvalidMeasurementID(s...)
|
||||||
l.WithCallerSkip(1).Error(e.Error())
|
l.WithCallerSkip(1).Error(e.Error())
|
||||||
|
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResourceExpired returns Err
|
// ResourceExpired returns Err
|
||||||
func ResourceExpired(s ...string) *LibError {
|
func ResourceExpired(s ...string) *Err {
|
||||||
return newErr(Scope, code.ResourceExpired, fmt.Sprintf("resource expired: %s", strings.Join(s, " ")))
|
return newErr(Scope, code.ResourceExpired, fmt.Sprintf("resource expired: %s", strings.Join(s, " ")))
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResourceExpiredL logs error message and returns Err
|
// ResourceExpiredL logs error message and returns Err
|
||||||
func ResourceExpiredL(l logx.Logger, s ...string) *LibError {
|
func ResourceExpiredL(l logx.Logger, s ...string) *Err {
|
||||||
e := ResourceExpired(s...)
|
e := ResourceExpired(s...)
|
||||||
l.WithCallerSkip(1).Error(e.Error())
|
l.WithCallerSkip(1).Error(e.Error())
|
||||||
|
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResourceMigrated returns Err
|
// ResourceMigrated returns Err
|
||||||
func ResourceMigrated(s ...string) *LibError {
|
func ResourceMigrated(s ...string) *Err {
|
||||||
return newErr(Scope, code.ResourceMigrated, fmt.Sprintf("resource migrated: %s", strings.Join(s, " ")))
|
return newErr(Scope, code.ResourceMigrated, fmt.Sprintf("resource migrated: %s", strings.Join(s, " ")))
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResourceMigratedL logs error message and returns Err
|
// ResourceMigratedL logs error message and returns Err
|
||||||
func ResourceMigratedL(l logx.Logger, s ...string) *LibError {
|
func ResourceMigratedL(l logx.Logger, s ...string) *Err {
|
||||||
e := ResourceMigrated(s...)
|
e := ResourceMigrated(s...)
|
||||||
l.WithCallerSkip(1).Error(e.Error())
|
l.WithCallerSkip(1).Error(e.Error())
|
||||||
|
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
// InsufficientQuota returns Err
|
// InsufficientQuota returns Err
|
||||||
func InsufficientQuota(s ...string) *LibError {
|
func InsufficientQuota(s ...string) *Err {
|
||||||
return newErr(Scope, code.InsufficientQuota, fmt.Sprintf("insufficient quota: %s", strings.Join(s, " ")))
|
return newErr(Scope, code.InsufficientQuota, fmt.Sprintf("insufficient quota: %s", strings.Join(s, " ")))
|
||||||
}
|
}
|
||||||
|
|
||||||
// InsufficientQuotaL logs error message and returns Err
|
// InsufficientQuotaL logs error message and returns Err
|
||||||
func InsufficientQuotaL(l logx.Logger, s ...string) *LibError {
|
func InsufficientQuotaL(l logx.Logger, s ...string) *Err {
|
||||||
e := InsufficientQuota(s...)
|
e := InsufficientQuota(s...)
|
||||||
l.WithCallerSkip(1).Error(e.Error())
|
l.WithCallerSkip(1).Error(e.Error())
|
||||||
|
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** CatAuth ***/
|
/*** CatAuth ***/
|
||||||
|
|
||||||
// Unauthorized returns Err
|
// Unauthorized returns Err
|
||||||
func Unauthorized(s ...string) *LibError {
|
func Unauthorized(s ...string) *Err {
|
||||||
return newErr(Scope, code.Unauthorized, fmt.Sprintf("unauthorized: %s", strings.Join(s, " ")))
|
return newErr(Scope, code.Unauthorized, fmt.Sprintf("unauthorized: %s", strings.Join(s, " ")))
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnauthorizedL logs error message and returns Err
|
// UnauthorizedL logs error message and returns Err
|
||||||
func UnauthorizedL(l logx.Logger, s ...string) *LibError {
|
func UnauthorizedL(l logx.Logger, s ...string) *Err {
|
||||||
e := Unauthorized(s...)
|
e := Unauthorized(s...)
|
||||||
l.WithCallerSkip(1).Error(e.Error())
|
l.WithCallerSkip(1).Error(e.Error())
|
||||||
|
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
// AuthExpired returns Err
|
// AuthExpired returns Err
|
||||||
func AuthExpired(s ...string) *LibError {
|
func AuthExpired(s ...string) *Err {
|
||||||
return newErr(Scope, code.AuthExpired, fmt.Sprintf("expired: %s", strings.Join(s, " ")))
|
return newErr(Scope, code.AuthExpired, fmt.Sprintf("expired: %s", strings.Join(s, " ")))
|
||||||
}
|
}
|
||||||
|
|
||||||
// AuthExpiredL logs error message and returns Err
|
// AuthExpiredL logs error message and returns Err
|
||||||
func AuthExpiredL(l logx.Logger, s ...string) *LibError {
|
func AuthExpiredL(l logx.Logger, s ...string) *Err {
|
||||||
e := AuthExpired(s...)
|
e := AuthExpired(s...)
|
||||||
l.WithCallerSkip(1).Error(e.Error())
|
l.WithCallerSkip(1).Error(e.Error())
|
||||||
|
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
// InvalidPosixTime returns Err
|
// InvalidPosixTime returns Err
|
||||||
func InvalidPosixTime(s ...string) *LibError {
|
func InvalidPosixTime(s ...string) *Err {
|
||||||
return newErr(Scope, code.InvalidPosixTime, fmt.Sprintf("invalid posix time: %s", strings.Join(s, " ")))
|
return newErr(Scope, code.InvalidPosixTime, fmt.Sprintf("invalid posix time: %s", strings.Join(s, " ")))
|
||||||
}
|
}
|
||||||
|
|
||||||
// InvalidPosixTimeL logs error message and returns Err
|
// InvalidPosixTimeL logs error message and returns Err
|
||||||
func InvalidPosixTimeL(l logx.Logger, s ...string) *LibError {
|
func InvalidPosixTimeL(l logx.Logger, s ...string) *Err {
|
||||||
e := InvalidPosixTime(s...)
|
e := InvalidPosixTime(s...)
|
||||||
l.WithCallerSkip(1).Error(e.Error())
|
l.WithCallerSkip(1).Error(e.Error())
|
||||||
|
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
// SigAndPayloadNotMatched returns Err
|
// SigAndPayloadNotMatched returns Err
|
||||||
func SigAndPayloadNotMatched(s ...string) *LibError {
|
func SigAndPayloadNotMatched(s ...string) *Err {
|
||||||
return newErr(Scope, code.SigAndPayloadNotMatched, fmt.Sprintf("signature and the payload are not match: %s", strings.Join(s, " ")))
|
return newErr(Scope, code.SigAndPayloadNotMatched, fmt.Sprintf("signature and the payload are not match: %s", strings.Join(s, " ")))
|
||||||
}
|
}
|
||||||
|
|
||||||
// SigAndPayloadNotMatchedL logs error message and returns Err
|
// SigAndPayloadNotMatchedL logs error message and returns Err
|
||||||
func SigAndPayloadNotMatchedL(l logx.Logger, s ...string) *LibError {
|
func SigAndPayloadNotMatchedL(l logx.Logger, s ...string) *Err {
|
||||||
e := SigAndPayloadNotMatched(s...)
|
e := SigAndPayloadNotMatched(s...)
|
||||||
l.WithCallerSkip(1).Error(e.Error())
|
l.WithCallerSkip(1).Error(e.Error())
|
||||||
|
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forbidden returns Err
|
// Forbidden returns Err
|
||||||
func Forbidden(s ...string) *LibError {
|
func Forbidden(s ...string) *Err {
|
||||||
return newErr(Scope, code.Forbidden, fmt.Sprintf("forbidden: %s", strings.Join(s, " ")))
|
return newErr(Scope, code.Forbidden, fmt.Sprintf("forbidden: %s", strings.Join(s, " ")))
|
||||||
}
|
}
|
||||||
|
|
||||||
// ForbiddenL logs error message and returns Err
|
// ForbiddenL logs error message and returns Err
|
||||||
func ForbiddenL(l logx.Logger, s ...string) *LibError {
|
func ForbiddenL(l logx.Logger, s ...string) *Err {
|
||||||
e := Forbidden(s...)
|
e := Forbidden(s...)
|
||||||
l.WithCallerSkip(1).Error(e.Error())
|
l.WithCallerSkip(1).Error(e.Error())
|
||||||
|
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsAuthUnauthorizedError check the err is unauthorized error
|
// IsAuthUnauthorizedError check the err is unauthorized error
|
||||||
func IsAuthUnauthorizedError(err *LibError) bool {
|
func IsAuthUnauthorizedError(err *Err) bool {
|
||||||
switch err.Code() {
|
switch err.Code() {
|
||||||
case code.Unauthorized, code.AuthExpired, code.InvalidPosixTime,
|
case code.Unauthorized, code.AuthExpired, code.InvalidPosixTime,
|
||||||
code.SigAndPayloadNotMatched, code.Forbidden,
|
code.SigAndPayloadNotMatched, code.Forbidden,
|
||||||
|
@ -425,47 +399,44 @@ func IsAuthUnauthorizedError(err *LibError) bool {
|
||||||
/*** CatXBC ***/
|
/*** CatXBC ***/
|
||||||
|
|
||||||
// ArkInternal returns Err
|
// ArkInternal returns Err
|
||||||
func ArkInternal(s ...string) *LibError {
|
func ArkInternal(s ...string) *Err {
|
||||||
return newErr(Scope, code.ArkInternal, fmt.Sprintf("ark internal error: %s", strings.Join(s, " ")))
|
return newErr(Scope, code.ArkInternal, fmt.Sprintf("ark internal error: %s", strings.Join(s, " ")))
|
||||||
}
|
}
|
||||||
|
|
||||||
// ArkInternalL logs error message and returns Err
|
// ArkInternalL logs error message and returns Err
|
||||||
func ArkInternalL(l logx.Logger, s ...string) *LibError {
|
func ArkInternalL(l logx.Logger, s ...string) *Err {
|
||||||
e := ArkInternal(s...)
|
e := ArkInternal(s...)
|
||||||
l.WithCallerSkip(1).Error(e.Error())
|
l.WithCallerSkip(1).Error(e.Error())
|
||||||
|
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** CatPubSub ***/
|
/*** CatPubSub ***/
|
||||||
|
|
||||||
// Publish returns Err
|
// Publish returns Err
|
||||||
func Publish(s ...string) *LibError {
|
func Publish(s ...string) *Err {
|
||||||
return newErr(Scope, code.Publish, fmt.Sprintf("publish: %s", strings.Join(s, " ")))
|
return newErr(Scope, code.Publish, fmt.Sprintf("publish: %s", strings.Join(s, " ")))
|
||||||
}
|
}
|
||||||
|
|
||||||
// PublishL logs error message and returns Err
|
// PublishL logs error message and returns Err
|
||||||
func PublishL(l logx.Logger, s ...string) *LibError {
|
func PublishL(l logx.Logger, s ...string) *Err {
|
||||||
e := Publish(s...)
|
e := Publish(s...)
|
||||||
l.WithCallerSkip(1).Error(e.Error())
|
l.WithCallerSkip(1).Error(e.Error())
|
||||||
|
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
// Consume returns Err
|
// Consume returns Err
|
||||||
func Consume(s ...string) *LibError {
|
func Consume(s ...string) *Err {
|
||||||
return newErr(Scope, code.Consume, fmt.Sprintf("consume: %s", strings.Join(s, " ")))
|
return newErr(Scope, code.Consume, fmt.Sprintf("consume: %s", strings.Join(s, " ")))
|
||||||
}
|
}
|
||||||
|
|
||||||
// MsgSizeTooLarge returns Err
|
// MsgSizeTooLarge returns Err
|
||||||
func MsgSizeTooLarge(s ...string) *LibError {
|
func MsgSizeTooLarge(s ...string) *Err {
|
||||||
return newErr(Scope, code.MsgSizeTooLarge, fmt.Sprintf("kafka error: %s", strings.Join(s, " ")))
|
return newErr(Scope, code.MsgSizeTooLarge, fmt.Sprintf("kafka error: %s", strings.Join(s, " ")))
|
||||||
}
|
}
|
||||||
|
|
||||||
// MsgSizeTooLargeL logs error message and returns Err
|
// MsgSizeTooLargeL logs error message and returns Err
|
||||||
func MsgSizeTooLargeL(l logx.Logger, s ...string) *LibError {
|
func MsgSizeTooLargeL(l logx.Logger, s ...string) *Err {
|
||||||
e := MsgSizeTooLarge(s...)
|
e := MsgSizeTooLarge(s...)
|
||||||
l.WithCallerSkip(1).Error(e.Error())
|
l.WithCallerSkip(1).Error(e.Error())
|
||||||
|
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package errors
|
package error
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"code.30cm.net/digimon/library-go/errors/code"
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -8,8 +9,6 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.30cm.net/digimon/library-go/errors/code"
|
|
||||||
|
|
||||||
"github.com/golang/mock/gomock"
|
"github.com/golang/mock/gomock"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
@ -75,7 +74,7 @@ func TestFromGRPCError_GivenGeneralError_ShouldReturnErr_Scope0_CatGRPC_DetailGR
|
||||||
|
|
||||||
func TestToGRPCError_GivenErr_StatusShouldHave_Code112233(t *testing.T) {
|
func TestToGRPCError_GivenErr_StatusShouldHave_Code112233(t *testing.T) {
|
||||||
// setup
|
// setup
|
||||||
e := LibError{scope: 11, code: 2233, msg: "FAKE MSG"}
|
e := Err{scope: 11, code: 2233, msg: "FAKE MSG"}
|
||||||
|
|
||||||
// act
|
// act
|
||||||
err := ToGRPCError(&e)
|
err := ToGRPCError(&e)
|
||||||
|
@ -999,7 +998,7 @@ func TestFromError(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
givenError error
|
givenError error
|
||||||
want *LibError
|
want *Err
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
"given nil error should return nil",
|
"given nil error should return nil",
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
package errors
|
package error
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
code2 "code.30cm.net/digimon/library-go/errors/code"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
code2 "code.30cm.net/digimon/library-go/errors/code"
|
|
||||||
|
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
)
|
)
|
||||||
|
@ -14,8 +13,8 @@ import (
|
||||||
// Scope 全域變數應由服務或模組設置
|
// Scope 全域變數應由服務或模組設置
|
||||||
var Scope = code2.Unset
|
var Scope = code2.Unset
|
||||||
|
|
||||||
// LibError 6 碼,服務 2, 大類 2, 詳細錯誤 2
|
// Err 6 碼,服務 2, 大類 2, 詳細錯誤 2
|
||||||
type LibError struct {
|
type Err struct {
|
||||||
category uint32
|
category uint32
|
||||||
code uint32
|
code uint32
|
||||||
scope uint32
|
scope uint32
|
||||||
|
@ -25,7 +24,7 @@ type LibError struct {
|
||||||
|
|
||||||
// Error 是錯誤的介面
|
// Error 是錯誤的介面
|
||||||
// 私有屬性 "msg" 的 getter 函數
|
// 私有屬性 "msg" 的 getter 函數
|
||||||
func (e *LibError) Error() string {
|
func (e *Err) Error() string {
|
||||||
if e == nil {
|
if e == nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
@ -40,7 +39,6 @@ func (e *LibError) Error() string {
|
||||||
if internalErrStr != "" {
|
if internalErrStr != "" {
|
||||||
return fmt.Sprintf("%s: %s", e.msg, internalErrStr)
|
return fmt.Sprintf("%s: %s", e.msg, internalErrStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
return e.msg
|
return e.msg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,21 +46,19 @@ func (e *LibError) Error() string {
|
||||||
if internalErrStr != "" {
|
if internalErrStr != "" {
|
||||||
return fmt.Sprintf("%s: %s", generalErrStr, internalErrStr)
|
return fmt.Sprintf("%s: %s", generalErrStr, internalErrStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
return generalErrStr
|
return generalErrStr
|
||||||
}
|
}
|
||||||
|
|
||||||
// Category 私有屬性 "category" 的 getter 函數
|
// Category 私有屬性 "category" 的 getter 函數
|
||||||
func (e *LibError) Category() uint32 {
|
func (e *Err) Category() uint32 {
|
||||||
if e == nil {
|
if e == nil {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
return e.category
|
return e.category
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scope 私有屬性 "scope" 的 getter 函數
|
// Scope 私有屬性 "scope" 的 getter 函數
|
||||||
func (e *LibError) Scope() uint32 {
|
func (e *Err) Scope() uint32 {
|
||||||
if e == nil {
|
if e == nil {
|
||||||
return code2.Unset
|
return code2.Unset
|
||||||
}
|
}
|
||||||
|
@ -71,7 +67,7 @@ func (e *LibError) Scope() uint32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
// CodeStr 返回帶有零填充的錯誤代碼字串
|
// CodeStr 返回帶有零填充的錯誤代碼字串
|
||||||
func (e *LibError) CodeStr() string {
|
func (e *Err) CodeStr() string {
|
||||||
if e == nil {
|
if e == nil {
|
||||||
return "00000"
|
return "00000"
|
||||||
}
|
}
|
||||||
|
@ -84,7 +80,7 @@ func (e *LibError) CodeStr() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Code 私有屬性 "code" 的 getter 函數
|
// Code 私有屬性 "code" 的 getter 函數
|
||||||
func (e *LibError) Code() uint32 {
|
func (e *Err) Code() uint32 {
|
||||||
if e == nil {
|
if e == nil {
|
||||||
return code2.OK
|
return code2.OK
|
||||||
}
|
}
|
||||||
|
@ -92,7 +88,7 @@ func (e *LibError) Code() uint32 {
|
||||||
return e.code
|
return e.code
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *LibError) FullCode() uint32 {
|
func (e *Err) FullCode() uint32 {
|
||||||
if e == nil {
|
if e == nil {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
@ -105,7 +101,7 @@ func (e *LibError) FullCode() uint32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTTPStatus 返回對應的 HTTP 狀態碼
|
// HTTPStatus 返回對應的 HTTP 狀態碼
|
||||||
func (e *LibError) HTTPStatus() int {
|
func (e *Err) HTTPStatus() int {
|
||||||
if e == nil || e.Code() == code2.OK {
|
if e == nil || e.Code() == code2.OK {
|
||||||
return http.StatusOK
|
return http.StatusOK
|
||||||
}
|
}
|
||||||
|
@ -147,7 +143,7 @@ func (e *LibError) HTTPStatus() int {
|
||||||
|
|
||||||
// GeneralError 轉換 category 級別錯誤訊息
|
// GeneralError 轉換 category 級別錯誤訊息
|
||||||
// 這是給客戶或 API 調用者的一般錯誤訊息
|
// 這是給客戶或 API 調用者的一般錯誤訊息
|
||||||
func (e *LibError) GeneralError() string {
|
func (e *Err) GeneralError() string {
|
||||||
if e == nil {
|
if e == nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
@ -164,37 +160,34 @@ func (e *LibError) GeneralError() string {
|
||||||
// 除非你非常確定你在做什麼,否則不要直接使用這個函數。
|
// 除非你非常確定你在做什麼,否則不要直接使用這個函數。
|
||||||
// 請使用 errors.Is 代替。
|
// 請使用 errors.Is 代替。
|
||||||
// 此函數比較兩個錯誤變量是否都是 *Err,並且具有相同的 code(不檢查包裹的內部錯誤)
|
// 此函數比較兩個錯誤變量是否都是 *Err,並且具有相同的 code(不檢查包裹的內部錯誤)
|
||||||
func (e *LibError) Is(f error) bool {
|
func (e *Err) Is(f error) bool {
|
||||||
var err *LibError
|
var err *Err
|
||||||
ok := errors.As(f, &err)
|
ok := errors.As(f, &err)
|
||||||
if !ok {
|
if !ok {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return e.Code() == err.Code()
|
return e.Code() == err.Code()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unwrap 返回底層錯誤
|
// Unwrap 返回底層錯誤
|
||||||
// 解除包裹錯誤的結果本身可能具有 Unwrap 方法;
|
// 解除包裹錯誤的結果本身可能具有 Unwrap 方法;
|
||||||
// 我們稱通過反覆解除包裹產生的錯誤序列為錯誤鏈。
|
// 我們稱通過反覆解除包裹產生的錯誤序列為錯誤鏈。
|
||||||
func (e *LibError) Unwrap() error {
|
func (e *Err) Unwrap() error {
|
||||||
if e == nil {
|
if e == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return e.internalErr
|
return e.internalErr
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wrap 將內部錯誤設置到 Err 結構
|
// Wrap 將內部錯誤設置到 Err 結構
|
||||||
func (e *LibError) Wrap(internalErr error) *LibError {
|
func (e *Err) Wrap(internalErr error) *Err {
|
||||||
if e != nil {
|
if e != nil {
|
||||||
e.internalErr = internalErr
|
e.internalErr = internalErr
|
||||||
}
|
}
|
||||||
|
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *LibError) GRPCStatus() *status.Status {
|
func (e *Err) GRPCStatus() *status.Status {
|
||||||
if e == nil {
|
if e == nil {
|
||||||
return status.New(codes.OK, "")
|
return status.New(codes.OK, "")
|
||||||
}
|
}
|
||||||
|
@ -205,8 +198,8 @@ func (e *LibError) GRPCStatus() *status.Status {
|
||||||
// 工廠函數
|
// 工廠函數
|
||||||
|
|
||||||
// NewErr 創建新的 Err
|
// NewErr 創建新的 Err
|
||||||
func NewErr(scope, category, detail uint32, msg string) *LibError {
|
func NewErr(scope, category, detail uint32, msg string) *Err {
|
||||||
return &LibError{
|
return &Err{
|
||||||
category: category,
|
category: category,
|
||||||
code: detail,
|
code: detail,
|
||||||
scope: scope,
|
scope: scope,
|
||||||
|
@ -215,8 +208,8 @@ func NewErr(scope, category, detail uint32, msg string) *LibError {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewGRPCErr 創建新的 gRPC Err
|
// NewGRPCErr 創建新的 gRPC Err
|
||||||
func NewGRPCErr(scope, detail uint32, msg string) *LibError {
|
func NewGRPCErr(scope, detail uint32, msg string) *Err {
|
||||||
return &LibError{
|
return &Err{
|
||||||
category: code2.CatGRPC,
|
category: code2.CatGRPC,
|
||||||
code: detail,
|
code: detail,
|
||||||
scope: scope,
|
scope: scope,
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
package errors
|
package error
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
code2 "code.30cm.net/digimon/library-go/errors/code"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
code2 "code.30cm.net/digimon/library-go/errors/code"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
|
@ -15,7 +14,7 @@ import (
|
||||||
|
|
||||||
func TestCode_GivenNilReceiver_CodeReturnOK_CodeStrReturns00000(t *testing.T) {
|
func TestCode_GivenNilReceiver_CodeReturnOK_CodeStrReturns00000(t *testing.T) {
|
||||||
// setup
|
// setup
|
||||||
var e *LibError = nil
|
var e *Err = nil
|
||||||
|
|
||||||
// act & assert
|
// act & assert
|
||||||
assert.Equal(t, code2.OK, e.Code())
|
assert.Equal(t, code2.OK, e.Code())
|
||||||
|
@ -25,7 +24,7 @@ func TestCode_GivenNilReceiver_CodeReturnOK_CodeStrReturns00000(t *testing.T) {
|
||||||
|
|
||||||
func TestCode_GivenScope99DetailCode6687_ShouldReturn996687(t *testing.T) {
|
func TestCode_GivenScope99DetailCode6687_ShouldReturn996687(t *testing.T) {
|
||||||
// setup
|
// setup
|
||||||
e := LibError{scope: 99, code: 6687}
|
e := Err{scope: 99, code: 6687}
|
||||||
|
|
||||||
// act & assert
|
// act & assert
|
||||||
assert.Equal(t, uint32(6687), e.Code())
|
assert.Equal(t, uint32(6687), e.Code())
|
||||||
|
@ -34,7 +33,7 @@ func TestCode_GivenScope99DetailCode6687_ShouldReturn996687(t *testing.T) {
|
||||||
|
|
||||||
func TestCode_GivenScope0DetailCode87_ShouldReturn87(t *testing.T) {
|
func TestCode_GivenScope0DetailCode87_ShouldReturn87(t *testing.T) {
|
||||||
// setup
|
// setup
|
||||||
e := LibError{scope: 0, code: 87}
|
e := Err{scope: 0, code: 87}
|
||||||
|
|
||||||
// act & assert
|
// act & assert
|
||||||
assert.Equal(t, uint32(87), e.Code())
|
assert.Equal(t, uint32(87), e.Code())
|
||||||
|
@ -88,7 +87,7 @@ func TestErr_ShouldImplementErrorFunction(t *testing.T) {
|
||||||
|
|
||||||
func TestGeneralError_GivenNilErr_ShouldReturnEmptyString(t *testing.T) {
|
func TestGeneralError_GivenNilErr_ShouldReturnEmptyString(t *testing.T) {
|
||||||
// setup
|
// setup
|
||||||
var e *LibError = nil
|
var e *Err = nil
|
||||||
|
|
||||||
// act & assert
|
// act & assert
|
||||||
assert.Equal(t, "", e.GeneralError())
|
assert.Equal(t, "", e.GeneralError())
|
||||||
|
@ -96,7 +95,7 @@ func TestGeneralError_GivenNilErr_ShouldReturnEmptyString(t *testing.T) {
|
||||||
|
|
||||||
func TestGeneralError_GivenNotExistCat_ShouldReturnEmptyString(t *testing.T) {
|
func TestGeneralError_GivenNotExistCat_ShouldReturnEmptyString(t *testing.T) {
|
||||||
// setup
|
// setup
|
||||||
e := LibError{category: 123456}
|
e := Err{category: 123456}
|
||||||
|
|
||||||
// act & assert
|
// act & assert
|
||||||
assert.Equal(t, "", e.GeneralError())
|
assert.Equal(t, "", e.GeneralError())
|
||||||
|
@ -104,7 +103,7 @@ func TestGeneralError_GivenNotExistCat_ShouldReturnEmptyString(t *testing.T) {
|
||||||
|
|
||||||
func TestGeneralError_GivenCatDB_ShouldReturnDBError(t *testing.T) {
|
func TestGeneralError_GivenCatDB_ShouldReturnDBError(t *testing.T) {
|
||||||
// setup
|
// setup
|
||||||
e := LibError{category: code2.CatDB}
|
e := Err{category: code2.CatDB}
|
||||||
catErrStr := code2.CatToStr[code2.CatDB]
|
catErrStr := code2.CatToStr[code2.CatDB]
|
||||||
|
|
||||||
// act & assert
|
// act & assert
|
||||||
|
@ -113,7 +112,7 @@ func TestGeneralError_GivenCatDB_ShouldReturnDBError(t *testing.T) {
|
||||||
|
|
||||||
func TestError_GivenEmptyMsg_ShouldReturnCatGeneralErrorMessage(t *testing.T) {
|
func TestError_GivenEmptyMsg_ShouldReturnCatGeneralErrorMessage(t *testing.T) {
|
||||||
// setup
|
// setup
|
||||||
e := LibError{category: code2.CatDB, msg: ""}
|
e := Err{category: code2.CatDB, msg: ""}
|
||||||
|
|
||||||
// act
|
// act
|
||||||
errMsg := e.Error()
|
errMsg := e.Error()
|
||||||
|
@ -124,7 +123,7 @@ func TestError_GivenEmptyMsg_ShouldReturnCatGeneralErrorMessage(t *testing.T) {
|
||||||
|
|
||||||
func TestError_GivenMsg_ShouldReturnGiveMsg(t *testing.T) {
|
func TestError_GivenMsg_ShouldReturnGiveMsg(t *testing.T) {
|
||||||
// setup
|
// setup
|
||||||
e := LibError{msg: "FAKE"}
|
e := Err{msg: "FAKE"}
|
||||||
|
|
||||||
// act
|
// act
|
||||||
errMsg := e.Error()
|
errMsg := e.Error()
|
||||||
|
@ -134,7 +133,7 @@ func TestError_GivenMsg_ShouldReturnGiveMsg(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestIs_GivenNilErr_ShouldReturnFalse(t *testing.T) {
|
func TestIs_GivenNilErr_ShouldReturnFalse(t *testing.T) {
|
||||||
var nilErrs *LibError
|
var nilErrs *Err
|
||||||
// act
|
// act
|
||||||
result := errors.Is(nilErrs, DBError())
|
result := errors.Is(nilErrs, DBError())
|
||||||
result2 := errors.Is(DBError(), nilErrs)
|
result2 := errors.Is(DBError(), nilErrs)
|
||||||
|
@ -155,7 +154,7 @@ func TestIs_GivenNil_ShouldReturnFalse(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestIs_GivenNilReceiver_ShouldReturnCorrectResult(t *testing.T) {
|
func TestIs_GivenNilReceiver_ShouldReturnCorrectResult(t *testing.T) {
|
||||||
var nilErr *LibError = nil
|
var nilErr *Err = nil
|
||||||
|
|
||||||
// test 1: nilErr != DBError
|
// test 1: nilErr != DBError
|
||||||
var dbErr error = DBError("fake db error")
|
var dbErr error = DBError("fake db error")
|
||||||
|
@ -166,7 +165,7 @@ func TestIs_GivenNilReceiver_ShouldReturnCorrectResult(t *testing.T) {
|
||||||
assert.False(t, nilErr.Is(nilError))
|
assert.False(t, nilErr.Is(nilError))
|
||||||
|
|
||||||
// test 3: nilErr == another nilErr
|
// test 3: nilErr == another nilErr
|
||||||
var nilErr2 *LibError = nil
|
var nilErr2 *Err = nil
|
||||||
assert.True(t, nilErr.Is(nilErr2))
|
assert.True(t, nilErr.Is(nilErr2))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,7 +198,7 @@ func TestIs_GivenDBErrorAssignToErrorType_ShouldReturnTrue(t *testing.T) {
|
||||||
func TestWrap_GivenNilErr_ShouldNoPanic(t *testing.T) {
|
func TestWrap_GivenNilErr_ShouldNoPanic(t *testing.T) {
|
||||||
// act & assert
|
// act & assert
|
||||||
assert.NotPanics(t, func() {
|
assert.NotPanics(t, func() {
|
||||||
var e *LibError = nil
|
var e *Err = nil
|
||||||
_ = e.Wrap(fmt.Errorf("test"))
|
_ = e.Wrap(fmt.Errorf("test"))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -214,19 +213,19 @@ func TestWrap_GivenErrorToWrap_ShouldReturnErrorWithWrappedError(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUnwrap_GivenNilErr_ShouldReturnNil(t *testing.T) {
|
func TestUnwrap_GivenNilErr_ShouldReturnNil(t *testing.T) {
|
||||||
var e *LibError = nil
|
var e *Err = nil
|
||||||
internalErr := e.Unwrap()
|
internalErr := e.Unwrap()
|
||||||
assert.Nil(t, internalErr)
|
assert.Nil(t, internalErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestErrorsIs_GivenNilErr_ShouldReturnFalse(t *testing.T) {
|
func TestErrorsIs_GivenNilErr_ShouldReturnFalse(t *testing.T) {
|
||||||
var e *LibError = nil
|
var e *Err = nil
|
||||||
assert.False(t, errors.Is(e, fmt.Errorf("test")))
|
assert.False(t, errors.Is(e, fmt.Errorf("test")))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestErrorsAs_GivenNilErr_ShouldReturnFalse(t *testing.T) {
|
func TestErrorsAs_GivenNilErr_ShouldReturnFalse(t *testing.T) {
|
||||||
var internalErr *testErr
|
var internalErr *testErr
|
||||||
var e *LibError = nil
|
var e *Err = nil
|
||||||
assert.False(t, errors.As(e, &internalErr))
|
assert.False(t, errors.As(e, &internalErr))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,7 +233,7 @@ func TestGRPCStatus(t *testing.T) {
|
||||||
// setup table driven tests
|
// setup table driven tests
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
given *LibError
|
given *Err
|
||||||
expect *status.Status
|
expect *status.Status
|
||||||
expectConvert error
|
expectConvert error
|
||||||
}{
|
}{
|
||||||
|
@ -266,24 +265,24 @@ func TestGRPCStatus(t *testing.T) {
|
||||||
func TestErr_HTTPStatus(t *testing.T) {
|
func TestErr_HTTPStatus(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
err *LibError
|
err *Err
|
||||||
want int
|
want int
|
||||||
}{
|
}{
|
||||||
{name: "nil error", err: nil, want: http.StatusOK},
|
{name: "nil error", err: nil, want: http.StatusOK},
|
||||||
{name: "invalid measurement id", err: &LibError{category: code2.CatResource, code: code2.InvalidMeasurementID}, want: http.StatusInternalServerError},
|
{name: "invalid measurement id", err: &Err{category: code2.CatResource, code: code2.InvalidMeasurementID}, want: http.StatusInternalServerError},
|
||||||
{name: "resource already exists", err: &LibError{category: code2.CatResource, code: code2.ResourceAlreadyExist}, want: http.StatusConflict},
|
{name: "resource already exists", err: &Err{category: code2.CatResource, code: code2.ResourceAlreadyExist}, want: http.StatusConflict},
|
||||||
{name: "invalid resource state", err: &LibError{category: code2.CatResource, code: code2.InvalidResourceState}, want: http.StatusConflict},
|
{name: "invalid resource state", err: &Err{category: code2.CatResource, code: code2.InvalidResourceState}, want: http.StatusConflict},
|
||||||
{name: "invalid posix time", err: &LibError{category: code2.CatAuth, code: code2.InvalidPosixTime}, want: http.StatusForbidden},
|
{name: "invalid posix time", err: &Err{category: code2.CatAuth, code: code2.InvalidPosixTime}, want: http.StatusForbidden},
|
||||||
{name: "unauthorized", err: &LibError{category: code2.CatAuth, code: code2.Unauthorized}, want: http.StatusUnauthorized},
|
{name: "unauthorized", err: &Err{category: code2.CatAuth, code: code2.Unauthorized}, want: http.StatusUnauthorized},
|
||||||
{name: "db error", err: &LibError{category: code2.CatDB, code: code2.DBError}, want: http.StatusInternalServerError},
|
{name: "db error", err: &Err{category: code2.CatDB, code: code2.DBError}, want: http.StatusInternalServerError},
|
||||||
{name: "insufficient permission", err: &LibError{category: code2.CatResource, code: code2.InsufficientPermission}, want: http.StatusUnauthorized},
|
{name: "insufficient permission", err: &Err{category: code2.CatResource, code: code2.InsufficientPermission}, want: http.StatusUnauthorized},
|
||||||
{name: "resource insufficient", err: &LibError{category: code2.CatResource, code: code2.ResourceInsufficient}, want: http.StatusBadRequest},
|
{name: "resource insufficient", err: &Err{category: code2.CatResource, code: code2.ResourceInsufficient}, want: http.StatusBadRequest},
|
||||||
{name: "invalid format", err: &LibError{category: code2.CatInput, code: code2.InvalidFormat}, want: http.StatusBadRequest},
|
{name: "invalid format", err: &Err{category: code2.CatInput, code: code2.InvalidFormat}, want: http.StatusBadRequest},
|
||||||
{name: "resource not found", err: &LibError{code: code2.ResourceNotFound}, want: http.StatusNotFound},
|
{name: "resource not found", err: &Err{code: code2.ResourceNotFound}, want: http.StatusNotFound},
|
||||||
{name: "ok", err: &LibError{code: code2.OK}, want: http.StatusOK},
|
{name: "ok", err: &Err{code: code2.OK}, want: http.StatusOK},
|
||||||
{name: "not valid implementation", err: &LibError{category: code2.CatInput, code: code2.NotValidImplementation}, want: http.StatusNotImplemented},
|
{name: "not valid implementation", err: &Err{category: code2.CatInput, code: code2.NotValidImplementation}, want: http.StatusNotImplemented},
|
||||||
{name: "forbidden", err: &LibError{category: code2.CatAuth, code: code2.Forbidden}, want: http.StatusForbidden},
|
{name: "forbidden", err: &Err{category: code2.CatAuth, code: code2.Forbidden}, want: http.StatusForbidden},
|
||||||
{name: "insufficient quota", err: &LibError{category: code2.CatResource, code: code2.InsufficientQuota}, want: http.StatusPaymentRequired},
|
{name: "insufficient quota", err: &Err{category: code2.CatResource, code: code2.InsufficientQuota}, want: http.StatusPaymentRequired},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
|
7
go.work
7
go.work
|
@ -1,7 +1,4 @@
|
||||||
go 1.22.3
|
go 1.22.3
|
||||||
|
|
||||||
use (
|
use ./errors
|
||||||
./errors
|
use ./validator
|
||||||
./validator
|
|
||||||
./worker_pool
|
|
||||||
)
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ package required
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/go-playground/validator/v10"
|
"github.com/go-playground/validator/v10"
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
module code.30cm.net/digimon/library-go/worker_pool
|
|
||||||
|
|
||||||
go 1.22.3
|
|
||||||
|
|
||||||
require (
|
|
||||||
github.com/panjf2000/ants/v2 v2.10.0
|
|
||||||
github.com/stretchr/testify v1.8.2
|
|
||||||
)
|
|
||||||
|
|
||||||
require (
|
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
|
||||||
golang.org/x/sync v0.3.0 // indirect
|
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
|
||||||
)
|
|
|
@ -1,71 +0,0 @@
|
||||||
package workerpool
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/panjf2000/ants/v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
const defaultWorkerPoolSize = 2000
|
|
||||||
|
|
||||||
type WorkerPool interface {
|
|
||||||
Submit(task func()) error
|
|
||||||
SubmitAndWaitAll(tasks ...func() error) (taskErr chan error, submitErr error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type workerPool struct {
|
|
||||||
p *ants.Pool
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewWorkerPool(size int) WorkerPool {
|
|
||||||
if size <= 0 {
|
|
||||||
size = defaultWorkerPoolSize
|
|
||||||
}
|
|
||||||
|
|
||||||
p, err := ants.NewPool(
|
|
||||||
size,
|
|
||||||
ants.WithDisablePurge(true),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return &workerPool{p: nil}
|
|
||||||
}
|
|
||||||
|
|
||||||
return &workerPool{p: p}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *workerPool) Submit(task func()) error {
|
|
||||||
if p.p == nil {
|
|
||||||
return ants.Submit(task)
|
|
||||||
}
|
|
||||||
|
|
||||||
return p.p.Submit(task)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *workerPool) SubmitAndWaitAll(tasks ...func() error) (chan error, error) {
|
|
||||||
taskErrCh := make(chan error, len(tasks))
|
|
||||||
submitErrCh := make(chan error, len(tasks))
|
|
||||||
wg := sync.WaitGroup{}
|
|
||||||
wg.Add(len(tasks))
|
|
||||||
|
|
||||||
for i := range tasks {
|
|
||||||
task := tasks[i]
|
|
||||||
err := p.Submit(func() {
|
|
||||||
defer wg.Done()
|
|
||||||
if err := task(); err != nil {
|
|
||||||
taskErrCh <- err
|
|
||||||
}
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
submitErrCh <- err
|
|
||||||
wg.Done()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
wg.Wait()
|
|
||||||
|
|
||||||
if len(submitErrCh) != 0 {
|
|
||||||
return nil, <-submitErrCh
|
|
||||||
}
|
|
||||||
|
|
||||||
return taskErrCh, nil
|
|
||||||
}
|
|
|
@ -1,89 +0,0 @@
|
||||||
package workerpool
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"sync"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestNewWorkerPool(t *testing.T) {
|
|
||||||
t.Run("default size pool", func(t *testing.T) {
|
|
||||||
pool := NewWorkerPool(0)
|
|
||||||
assert.NotNil(t, pool)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("custom size pool", func(t *testing.T) {
|
|
||||||
size := 100
|
|
||||||
pool := NewWorkerPool(size)
|
|
||||||
assert.NotNil(t, pool)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSubmit(t *testing.T) {
|
|
||||||
t.Run("submit task to worker pool", func(t *testing.T) {
|
|
||||||
pool := NewWorkerPool(10)
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
wg.Add(1)
|
|
||||||
|
|
||||||
err := pool.Submit(func() {
|
|
||||||
defer wg.Done()
|
|
||||||
time.Sleep(100 * time.Millisecond)
|
|
||||||
})
|
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
wg.Wait()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSubmitAndWaitAll(t *testing.T) {
|
|
||||||
t.Run("submit and wait all tasks succeed", func(t *testing.T) {
|
|
||||||
pool := NewWorkerPool(10)
|
|
||||||
tasks := []func() error{
|
|
||||||
func() error {
|
|
||||||
time.Sleep(100 * time.Millisecond)
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
func() error {
|
|
||||||
time.Sleep(50 * time.Millisecond)
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
taskErrCh, submitErr := pool.SubmitAndWaitAll(tasks...)
|
|
||||||
assert.NoError(t, submitErr)
|
|
||||||
close(taskErrCh)
|
|
||||||
for err := range taskErrCh {
|
|
||||||
assert.NoError(t, err)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("submit and wait all tasks with errors", func(t *testing.T) {
|
|
||||||
pool := NewWorkerPool(10)
|
|
||||||
expectedError := errors.New("task error")
|
|
||||||
tasks := []func() error{
|
|
||||||
func() error {
|
|
||||||
time.Sleep(100 * time.Millisecond)
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
func() error {
|
|
||||||
time.Sleep(50 * time.Millisecond)
|
|
||||||
return expectedError
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
taskErrCh, submitErr := pool.SubmitAndWaitAll(tasks...)
|
|
||||||
assert.NoError(t, submitErr)
|
|
||||||
close(taskErrCh)
|
|
||||||
foundError := false
|
|
||||||
for err := range taskErrCh {
|
|
||||||
if err != nil {
|
|
||||||
foundError = true
|
|
||||||
assert.Equal(t, expectedError, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assert.True(t, foundError)
|
|
||||||
})
|
|
||||||
}
|
|
Loading…
Reference in New Issue