468 lines
17 KiB
Go
468 lines
17 KiB
Go
package errs
|
||
|
||
import (
|
||
"strings"
|
||
|
||
"backend/pkg/library/errors/code"
|
||
)
|
||
|
||
/* =========================
|
||
日誌介面(與你現有 Logger 對齊)
|
||
========================= */
|
||
|
||
// Logger 你現有的 logger 介面(與外部一致即可)
|
||
type Logger interface {
|
||
WithCallerSkip(n int) Logger
|
||
WithFields(fields ...LogField) Logger
|
||
Error(msg string)
|
||
Warn(msg string)
|
||
Info(msg string)
|
||
}
|
||
|
||
// LogField 結構化欄位
|
||
type LogField struct {
|
||
Key string
|
||
Val any
|
||
}
|
||
|
||
/* =========================
|
||
共用小工具
|
||
========================= */
|
||
|
||
// joinMsg:把可變參數字串用空白串接(避免到處判斷 nil / 空 slice)
|
||
func joinMsg(s []string) string {
|
||
if len(s) == 0 {
|
||
return ""
|
||
}
|
||
|
||
return strings.Join(s, " ")
|
||
}
|
||
|
||
// logErr:統一打一筆 error log(避免重複記錄)
|
||
func logErr(l Logger, fields []LogField, e *Error) {
|
||
if l == nil || e == nil {
|
||
return
|
||
}
|
||
ll := l.WithCallerSkip(1)
|
||
if len(fields) > 0 {
|
||
ll = ll.WithFields(fields...)
|
||
}
|
||
// 需要更多欄位可在此擴充,例如:e.DisplayCode()、e.Category()、e.Detail()
|
||
ll.Error(e.Error())
|
||
}
|
||
|
||
/* =========================
|
||
共用裝飾器(把任意 ez 建構器包成帶日誌版本)
|
||
========================= */
|
||
|
||
// WithLog 將任一 *Error 建構器(如 SysTimeoutError)轉成帶日誌的版本
|
||
func WithLog(l Logger, fields []LogField, ctor func(s ...string) *Error, s ...string) *Error {
|
||
e := ctor(s...)
|
||
logErr(l, fields, e)
|
||
|
||
return e
|
||
}
|
||
|
||
// WithLogWrap 同上,但會同時 Wrap 內部 cause
|
||
func WithLogWrap(l Logger, fields []LogField, ctor func(s ...string) *Error, cause error, s ...string) *Error {
|
||
e := ctor(s...).Wrap(cause)
|
||
logErr(l, fields, e)
|
||
|
||
return e
|
||
}
|
||
|
||
/* =========================
|
||
泛用建構器(當你懶得記函式名時)
|
||
========================= */
|
||
|
||
// EL 依 Category/Detail 直接建構並記錄日誌
|
||
func EL(l Logger, fields []LogField, cat code.Category, det code.Detail, s ...string) *Error {
|
||
e := New(uint32(Scope), uint32(cat), uint32(det), joinMsg(s))
|
||
logErr(l, fields, e)
|
||
|
||
return e
|
||
}
|
||
|
||
// ELWrap 同上,並 Wrap cause
|
||
func ELWrap(l Logger, fields []LogField, cat code.Category, det code.Detail, cause error, s ...string) *Error {
|
||
e := New(uint32(Scope), uint32(cat), uint32(det), joinMsg(s)).Wrap(cause)
|
||
logErr(l, fields, e)
|
||
|
||
return e
|
||
}
|
||
|
||
/* =======================================================================
|
||
一、基礎 ez 建構器(純建構 *Error,不帶日誌)
|
||
分類順序:Input → DB → Resource → Auth → System → PubSub → Service
|
||
======================================================================= */
|
||
|
||
/* ----- Input (CatInput) ----- */
|
||
|
||
func InputInvalidFormatError(s ...string) *Error {
|
||
return New(uint32(Scope), uint32(code.InputInvalidFormat), 0, joinMsg(s))
|
||
}
|
||
func InputNotValidImplementationError(s ...string) *Error {
|
||
return New(uint32(Scope), uint32(code.InputNotValidImplementation), 0, joinMsg(s))
|
||
}
|
||
func InputInvalidRangeError(s ...string) *Error {
|
||
return New(uint32(Scope), uint32(code.InputInvalidRange), 0, joinMsg(s))
|
||
}
|
||
|
||
/* ----- DB (CatDB) ----- */
|
||
|
||
func DBErrorError(s ...string) *Error {
|
||
return New(uint32(Scope), uint32(code.DBError), 0, joinMsg(s))
|
||
}
|
||
func DBDataConvertError(s ...string) *Error {
|
||
return New(uint32(Scope), uint32(code.DBDataConvert), 0, joinMsg(s))
|
||
}
|
||
func DBDuplicateError(s ...string) *Error {
|
||
return New(uint32(Scope), uint32(code.DBDuplicate), 0, joinMsg(s))
|
||
}
|
||
|
||
/* ----- Resource (CatResource) ----- */
|
||
|
||
func ResNotFoundError(s ...string) *Error {
|
||
return New(uint32(Scope), uint32(code.ResNotFound), 0, joinMsg(s))
|
||
}
|
||
func ResInvalidFormatError(s ...string) *Error {
|
||
return New(uint32(Scope), uint32(code.ResInvalidFormat), 0, joinMsg(s))
|
||
}
|
||
func ResAlreadyExistError(s ...string) *Error {
|
||
return New(uint32(Scope), uint32(code.ResAlreadyExist), 0, joinMsg(s))
|
||
}
|
||
func ResInsufficientError(s ...string) *Error {
|
||
return New(uint32(Scope), uint32(code.ResInsufficient), 0, joinMsg(s))
|
||
}
|
||
func ResInsufficientPermError(s ...string) *Error {
|
||
return New(uint32(Scope), uint32(code.ResInsufficientPerm), 0, joinMsg(s))
|
||
}
|
||
func ResInvalidMeasureIDError(s ...string) *Error {
|
||
return New(uint32(Scope), uint32(code.ResInvalidMeasureID), 0, joinMsg(s))
|
||
}
|
||
func ResExpiredError(s ...string) *Error {
|
||
return New(uint32(Scope), uint32(code.ResExpired), 0, joinMsg(s))
|
||
}
|
||
func ResMigratedError(s ...string) *Error {
|
||
return New(uint32(Scope), uint32(code.ResMigrated), 0, joinMsg(s))
|
||
}
|
||
func ResInvalidStateError(s ...string) *Error {
|
||
return New(uint32(Scope), uint32(code.ResInvalidState), 0, joinMsg(s))
|
||
}
|
||
func ResInsufficientQuotaError(s ...string) *Error {
|
||
return New(uint32(Scope), uint32(code.ResInsufficientQuota), 0, joinMsg(s))
|
||
}
|
||
func ResMultiOwnerError(s ...string) *Error {
|
||
return New(uint32(Scope), uint32(code.ResMultiOwner), 0, joinMsg(s))
|
||
}
|
||
|
||
/* ----- Auth (CatAuth) ----- */
|
||
|
||
func AuthUnauthorizedError(s ...string) *Error {
|
||
return New(uint32(Scope), uint32(code.AuthUnauthorized), 0, joinMsg(s))
|
||
}
|
||
func AuthExpiredError(s ...string) *Error {
|
||
return New(uint32(Scope), uint32(code.AuthExpired), 0, joinMsg(s))
|
||
}
|
||
func AuthInvalidPosixTimeError(s ...string) *Error {
|
||
return New(uint32(Scope), uint32(code.AuthInvalidPosixTime), 0, joinMsg(s))
|
||
}
|
||
func AuthSigPayloadMismatchError(s ...string) *Error {
|
||
return New(uint32(Scope), uint32(code.AuthSigPayloadMismatch), 0, joinMsg(s))
|
||
}
|
||
func AuthForbiddenError(s ...string) *Error {
|
||
return New(uint32(Scope), uint32(code.AuthForbidden), 0, joinMsg(s))
|
||
}
|
||
|
||
/* ----- System (CatSystem) ----- */
|
||
|
||
func SysInternalError(s ...string) *Error {
|
||
return New(uint32(Scope), uint32(code.SysInternal), 0, joinMsg(s))
|
||
}
|
||
func SysMaintainError(s ...string) *Error {
|
||
return New(uint32(Scope), uint32(code.SysMaintain), 0, joinMsg(s))
|
||
}
|
||
func SysTimeoutError(s ...string) *Error {
|
||
return New(uint32(Scope), uint32(code.SysTimeout), 0, joinMsg(s))
|
||
}
|
||
func SysTooManyRequestError(s ...string) *Error {
|
||
return New(uint32(Scope), uint32(code.SysTooManyRequest), 0, joinMsg(s))
|
||
}
|
||
|
||
/* ----- PubSub (CatPubSub) ----- */
|
||
|
||
func PSuPublishError(s ...string) *Error {
|
||
return New(uint32(Scope), uint32(code.PSuPublish), 0, joinMsg(s))
|
||
}
|
||
func PSuConsumeError(s ...string) *Error {
|
||
return New(uint32(Scope), uint32(code.PSuConsume), 0, joinMsg(s))
|
||
}
|
||
func PSuTooLargeError(s ...string) *Error {
|
||
return New(uint32(Scope), uint32(code.PSuTooLarge), 0, joinMsg(s))
|
||
}
|
||
|
||
/* ----- Service (CatService) ----- */
|
||
|
||
func SvcInternalError(s ...string) *Error {
|
||
return New(uint32(Scope), uint32(code.SvcInternal), 0, joinMsg(s))
|
||
}
|
||
func SvcThirdPartyError(s ...string) *Error {
|
||
return New(uint32(Scope), uint32(code.SvcThirdParty), 0, joinMsg(s))
|
||
}
|
||
func SvcHTTP400Error(s ...string) *Error {
|
||
return New(uint32(Scope), uint32(code.SvcHTTP400), 0, joinMsg(s))
|
||
}
|
||
func SvcMaintenanceError(s ...string) *Error {
|
||
return New(uint32(Scope), uint32(code.SvcMaintenance), 0, joinMsg(s))
|
||
}
|
||
|
||
/* =============================================================================
|
||
二、帶日誌版本:L / WrapL(在「基礎 ez 建構器」之上包裝 WithLog / WithLogWrap)
|
||
分類順序同上:Input → DB → Resource → Auth → System → PubSub → Service
|
||
============================================================================= */
|
||
|
||
/* ----- Input (CatInput) ----- */
|
||
|
||
func InputInvalidFormatErrorL(l Logger, fields []LogField, s ...string) *Error {
|
||
return WithLog(l, fields, InputInvalidFormatError, s...)
|
||
}
|
||
func InputInvalidFormatErrorWrapL(l Logger, fields []LogField, cause error, s ...string) *Error {
|
||
return WithLogWrap(l, fields, InputInvalidFormatError, cause, s...)
|
||
}
|
||
|
||
func InputNotValidImplementationErrorL(l Logger, fields []LogField, s ...string) *Error {
|
||
return WithLog(l, fields, InputNotValidImplementationError, s...)
|
||
}
|
||
func InputNotValidImplementationErrorWrapL(l Logger, fields []LogField, cause error, s ...string) *Error {
|
||
return WithLogWrap(l, fields, InputNotValidImplementationError, cause, s...)
|
||
}
|
||
|
||
func InputInvalidRangeErrorL(l Logger, fields []LogField, s ...string) *Error {
|
||
return WithLog(l, fields, InputInvalidRangeError, s...)
|
||
}
|
||
func InputInvalidRangeErrorWrapL(l Logger, fields []LogField, cause error, s ...string) *Error {
|
||
return WithLogWrap(l, fields, InputInvalidRangeError, cause, s...)
|
||
}
|
||
|
||
/* ----- DB (CatDB) ----- */
|
||
|
||
func DBErrorErrorL(l Logger, fields []LogField, s ...string) *Error {
|
||
return WithLog(l, fields, DBErrorError, s...)
|
||
}
|
||
func DBErrorErrorWrapL(l Logger, fields []LogField, cause error, s ...string) *Error {
|
||
return WithLogWrap(l, fields, DBErrorError, cause, s...)
|
||
}
|
||
|
||
func DBDataConvertErrorL(l Logger, fields []LogField, s ...string) *Error {
|
||
return WithLog(l, fields, DBDataConvertError, s...)
|
||
}
|
||
func DBDataConvertErrorWrapL(l Logger, fields []LogField, cause error, s ...string) *Error {
|
||
return WithLogWrap(l, fields, DBDataConvertError, cause, s...)
|
||
}
|
||
|
||
func DBDuplicateErrorL(l Logger, fields []LogField, s ...string) *Error {
|
||
return WithLog(l, fields, DBDuplicateError, s...)
|
||
}
|
||
func DBDuplicateErrorWrapL(l Logger, fields []LogField, cause error, s ...string) *Error {
|
||
return WithLogWrap(l, fields, DBDuplicateError, cause, s...)
|
||
}
|
||
|
||
/* ----- Resource (CatResource) ----- */
|
||
|
||
func ResNotFoundErrorL(l Logger, fields []LogField, s ...string) *Error {
|
||
return WithLog(l, fields, ResNotFoundError, s...)
|
||
}
|
||
func ResNotFoundErrorWrapL(l Logger, fields []LogField, cause error, s ...string) *Error {
|
||
return WithLogWrap(l, fields, ResNotFoundError, cause, s...)
|
||
}
|
||
|
||
func ResInvalidFormatErrorL(l Logger, fields []LogField, s ...string) *Error {
|
||
return WithLog(l, fields, ResInvalidFormatError, s...)
|
||
}
|
||
func ResInvalidFormatErrorWrapL(l Logger, fields []LogField, cause error, s ...string) *Error {
|
||
return WithLogWrap(l, fields, ResInvalidFormatError, cause, s...)
|
||
}
|
||
|
||
func ResAlreadyExistErrorL(l Logger, fields []LogField, s ...string) *Error {
|
||
return WithLog(l, fields, ResAlreadyExistError, s...)
|
||
}
|
||
func ResAlreadyExistErrorWrapL(l Logger, fields []LogField, cause error, s ...string) *Error {
|
||
return WithLogWrap(l, fields, ResAlreadyExistError, cause, s...)
|
||
}
|
||
|
||
func ResInsufficientErrorL(l Logger, fields []LogField, s ...string) *Error {
|
||
return WithLog(l, fields, ResInsufficientError, s...)
|
||
}
|
||
func ResInsufficientErrorWrapL(l Logger, fields []LogField, cause error, s ...string) *Error {
|
||
return WithLogWrap(l, fields, ResInsufficientError, cause, s...)
|
||
}
|
||
|
||
func ResInsufficientPermErrorL(l Logger, fields []LogField, s ...string) *Error {
|
||
return WithLog(l, fields, ResInsufficientPermError, s...)
|
||
}
|
||
func ResInsufficientPermErrorWrapL(l Logger, fields []LogField, cause error, s ...string) *Error {
|
||
return WithLogWrap(l, fields, ResInsufficientPermError, cause, s...)
|
||
}
|
||
|
||
func ResInvalidMeasureIDErrorL(l Logger, fields []LogField, s ...string) *Error {
|
||
return WithLog(l, fields, ResInvalidMeasureIDError, s...)
|
||
}
|
||
func ResInvalidMeasureIDErrorWrapL(l Logger, fields []LogField, cause error, s ...string) *Error {
|
||
return WithLogWrap(l, fields, ResInvalidMeasureIDError, cause, s...)
|
||
}
|
||
|
||
func ResExpiredErrorL(l Logger, fields []LogField, s ...string) *Error {
|
||
return WithLog(l, fields, ResExpiredError, s...)
|
||
}
|
||
func ResExpiredErrorWrapL(l Logger, fields []LogField, cause error, s ...string) *Error {
|
||
return WithLogWrap(l, fields, ResExpiredError, cause, s...)
|
||
}
|
||
|
||
func ResMigratedErrorL(l Logger, fields []LogField, s ...string) *Error {
|
||
return WithLog(l, fields, ResMigratedError, s...)
|
||
}
|
||
func ResMigratedErrorWrapL(l Logger, fields []LogField, cause error, s ...string) *Error {
|
||
return WithLogWrap(l, fields, ResMigratedError, cause, s...)
|
||
}
|
||
|
||
func ResInvalidStateErrorL(l Logger, fields []LogField, s ...string) *Error {
|
||
return WithLog(l, fields, ResInvalidStateError, s...)
|
||
}
|
||
func ResInvalidStateErrorWrapL(l Logger, fields []LogField, cause error, s ...string) *Error {
|
||
return WithLogWrap(l, fields, ResInvalidStateError, cause, s...)
|
||
}
|
||
|
||
func ResInsufficientQuotaErrorL(l Logger, fields []LogField, s ...string) *Error {
|
||
return WithLog(l, fields, ResInsufficientQuotaError, s...)
|
||
}
|
||
func ResInsufficientQuotaErrorWrapL(l Logger, fields []LogField, cause error, s ...string) *Error {
|
||
return WithLogWrap(l, fields, ResInsufficientQuotaError, cause, s...)
|
||
}
|
||
|
||
func ResMultiOwnerErrorL(l Logger, fields []LogField, s ...string) *Error {
|
||
return WithLog(l, fields, ResMultiOwnerError, s...)
|
||
}
|
||
func ResMultiOwnerErrorWrapL(l Logger, fields []LogField, cause error, s ...string) *Error {
|
||
return WithLogWrap(l, fields, ResMultiOwnerError, cause, s...)
|
||
}
|
||
|
||
/* ----- Auth (CatAuth) ----- */
|
||
|
||
func AuthUnauthorizedErrorL(l Logger, fields []LogField, s ...string) *Error {
|
||
return WithLog(l, fields, AuthUnauthorizedError, s...)
|
||
}
|
||
func AuthUnauthorizedErrorWrapL(l Logger, fields []LogField, cause error, s ...string) *Error {
|
||
return WithLogWrap(l, fields, AuthUnauthorizedError, cause, s...)
|
||
}
|
||
|
||
func AuthExpiredErrorL(l Logger, fields []LogField, s ...string) *Error {
|
||
return WithLog(l, fields, AuthExpiredError, s...)
|
||
}
|
||
func AuthExpiredErrorWrapL(l Logger, fields []LogField, cause error, s ...string) *Error {
|
||
return WithLogWrap(l, fields, AuthExpiredError, cause, s...)
|
||
}
|
||
|
||
func AuthInvalidPosixTimeErrorL(l Logger, fields []LogField, s ...string) *Error {
|
||
return WithLog(l, fields, AuthInvalidPosixTimeError, s...)
|
||
}
|
||
func AuthInvalidPosixTimeErrorWrapL(l Logger, fields []LogField, cause error, s ...string) *Error {
|
||
return WithLogWrap(l, fields, AuthInvalidPosixTimeError, cause, s...)
|
||
}
|
||
|
||
func AuthSigPayloadMismatchErrorL(l Logger, fields []LogField, s ...string) *Error {
|
||
return WithLog(l, fields, AuthSigPayloadMismatchError, s...)
|
||
}
|
||
func AuthSigPayloadMismatchErrorWrapL(l Logger, fields []LogField, cause error, s ...string) *Error {
|
||
return WithLogWrap(l, fields, AuthSigPayloadMismatchError, cause, s...)
|
||
}
|
||
|
||
func AuthForbiddenErrorL(l Logger, fields []LogField, s ...string) *Error {
|
||
return WithLog(l, fields, AuthForbiddenError, s...)
|
||
}
|
||
func AuthForbiddenErrorWrapL(l Logger, fields []LogField, cause error, s ...string) *Error {
|
||
return WithLogWrap(l, fields, AuthForbiddenError, cause, s...)
|
||
}
|
||
|
||
/* ----- System (CatSystem) ----- */
|
||
|
||
func SysInternalErrorL(l Logger, fields []LogField, s ...string) *Error {
|
||
return WithLog(l, fields, SysInternalError, s...)
|
||
}
|
||
func SysInternalErrorWrapL(l Logger, fields []LogField, cause error, s ...string) *Error {
|
||
return WithLogWrap(l, fields, SysInternalError, cause, s...)
|
||
}
|
||
|
||
func SysMaintainErrorL(l Logger, fields []LogField, s ...string) *Error {
|
||
return WithLog(l, fields, SysMaintainError, s...)
|
||
}
|
||
func SysMaintainErrorWrapL(l Logger, fields []LogField, cause error, s ...string) *Error {
|
||
return WithLogWrap(l, fields, SysMaintainError, cause, s...)
|
||
}
|
||
|
||
func SysTimeoutErrorL(l Logger, fields []LogField, s ...string) *Error {
|
||
return WithLog(l, fields, SysTimeoutError, s...)
|
||
}
|
||
func SysTimeoutErrorWrapL(l Logger, fields []LogField, cause error, s ...string) *Error {
|
||
return WithLogWrap(l, fields, SysTimeoutError, cause, s...)
|
||
}
|
||
|
||
func SysTooManyRequestErrorL(l Logger, fields []LogField, s ...string) *Error {
|
||
return WithLog(l, fields, SysTooManyRequestError, s...)
|
||
}
|
||
func SysTooManyRequestErrorWrapL(l Logger, fields []LogField, cause error, s ...string) *Error {
|
||
return WithLogWrap(l, fields, SysTooManyRequestError, cause, s...)
|
||
}
|
||
|
||
/* ----- PubSub (CatPubSub) ----- */
|
||
|
||
func PSuPublishErrorL(l Logger, fields []LogField, s ...string) *Error {
|
||
return WithLog(l, fields, PSuPublishError, s...)
|
||
}
|
||
func PSuPublishErrorWrapL(l Logger, fields []LogField, cause error, s ...string) *Error {
|
||
return WithLogWrap(l, fields, PSuPublishError, cause, s...)
|
||
}
|
||
|
||
func PSuConsumeErrorL(l Logger, fields []LogField, s ...string) *Error {
|
||
return WithLog(l, fields, PSuConsumeError, s...)
|
||
}
|
||
func PSuConsumeErrorWrapL(l Logger, fields []LogField, cause error, s ...string) *Error {
|
||
return WithLogWrap(l, fields, PSuConsumeError, cause, s...)
|
||
}
|
||
|
||
func PSuTooLargeErrorL(l Logger, fields []LogField, s ...string) *Error {
|
||
return WithLog(l, fields, PSuTooLargeError, s...)
|
||
}
|
||
func PSuTooLargeErrorWrapL(l Logger, fields []LogField, cause error, s ...string) *Error {
|
||
return WithLogWrap(l, fields, PSuTooLargeError, cause, s...)
|
||
}
|
||
|
||
/* ----- Service (CatService) ----- */
|
||
|
||
func SvcInternalErrorL(l Logger, fields []LogField, s ...string) *Error {
|
||
return WithLog(l, fields, SvcInternalError, s...)
|
||
}
|
||
func SvcInternalErrorWrapL(l Logger, fields []LogField, cause error, s ...string) *Error {
|
||
return WithLogWrap(l, fields, SvcInternalError, cause, s...)
|
||
}
|
||
|
||
func SvcThirdPartyErrorL(l Logger, fields []LogField, s ...string) *Error {
|
||
return WithLog(l, fields, SvcThirdPartyError, s...)
|
||
}
|
||
func SvcThirdPartyErrorWrapL(l Logger, fields []LogField, cause error, s ...string) *Error {
|
||
return WithLogWrap(l, fields, SvcThirdPartyError, cause, s...)
|
||
}
|
||
|
||
func SvcHTTP400ErrorL(l Logger, fields []LogField, s ...string) *Error {
|
||
return WithLog(l, fields, SvcHTTP400Error, s...)
|
||
}
|
||
func SvcHTTP400ErrorWrapL(l Logger, fields []LogField, cause error, s ...string) *Error {
|
||
return WithLogWrap(l, fields, SvcHTTP400Error, cause, s...)
|
||
}
|
||
|
||
func SvcMaintenanceErrorL(l Logger, fields []LogField, s ...string) *Error {
|
||
return WithLog(l, fields, SvcMaintenanceError, s...)
|
||
}
|
||
func SvcMaintenanceErrorWrapL(l Logger, fields []LogField, cause error, s ...string) *Error {
|
||
return WithLogWrap(l, fields, SvcMaintenanceError, cause, s...)
|
||
}
|