feat(error): Create api error. WIP
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
a7b1989231
commit
77b4351ef1
109
aerr/aerr.go
Normal file
109
aerr/aerr.go
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
package aerr
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Error represent a API Error. It will mainly be used in the Handler.
|
||||||
|
type Error struct {
|
||||||
|
// shown in Json
|
||||||
|
Code int `json:"code"`
|
||||||
|
DebugId string `json:"debug_id"`
|
||||||
|
Msg string `json:"message"`
|
||||||
|
|
||||||
|
// not in Json
|
||||||
|
httpCode int `json:"-"`
|
||||||
|
origin error `json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error implements error interface.
|
||||||
|
func (e *Error) Error() string {
|
||||||
|
s := fmt.Sprintf("Error: %d.", e.Code)
|
||||||
|
|
||||||
|
// if we have a message, add it
|
||||||
|
if e.Msg != "" {
|
||||||
|
s = fmt.Sprintf("%s Message: %s.", s, e.Msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we have an origin message, add it.
|
||||||
|
if e.origin != nil {
|
||||||
|
s = fmt.Sprintf("%s Origin Message: %s.", s, e.origin.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// add debugId
|
||||||
|
if e.DebugId != "" {
|
||||||
|
s = fmt.Sprintf("%s - %s", s, e.DebugId)
|
||||||
|
}
|
||||||
|
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON will JSON marshal an Error. It will try to get message from the origin if there is none in the current Error.
|
||||||
|
func (e *Error) MarshalJSON() ([]byte, error) {
|
||||||
|
type TmpJson Error
|
||||||
|
|
||||||
|
// let's get the origin message if the current message is empty
|
||||||
|
if e.Msg == "" && e.origin != nil {
|
||||||
|
var originE *Error
|
||||||
|
|
||||||
|
if errors.As(e.origin, &originE) {
|
||||||
|
e.Msg = originE.Message()
|
||||||
|
} else {
|
||||||
|
e.Msg = e.origin.Error()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return json.Marshal((*TmpJson)(e))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a bunch of setter / Getter
|
||||||
|
|
||||||
|
// SetDebugID allow to overide/set a debug Id and return the error.
|
||||||
|
func (e *Error) SetDebugID(d string) *Error {
|
||||||
|
e.DebugId = d
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetOrigin allow to set an origin error to the error and return that error.
|
||||||
|
func (e *Error) SetOrigin(origin error) *Error {
|
||||||
|
e.origin = origin
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetMessage allow to set a message to the error and return that error.
|
||||||
|
func (e *Error) SetMessage(msg string) *Error {
|
||||||
|
e.Msg = msg
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetCode allow to set a specific code to the error and return that error.
|
||||||
|
func (e *Error) SetCode(code int) *Error {
|
||||||
|
e.httpCode = code
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Message will get the current error Msg. If none, it will try to go to origins until finding a message.
|
||||||
|
func (e *Error) Message() string {
|
||||||
|
if e.Msg == "" && e.origin != nil {
|
||||||
|
var originE *Error
|
||||||
|
|
||||||
|
if errors.As(e.origin, &originE) {
|
||||||
|
return originE.Message()
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.origin.Error()
|
||||||
|
}
|
||||||
|
return e.Msg
|
||||||
|
}
|
||||||
|
|
||||||
|
// HttpCode will return the http code of the error.
|
||||||
|
func (e *Error) HttpCode() int {
|
||||||
|
return e.httpCode
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unwrap will return the origin error.
|
||||||
|
func (e *Error) Unwrap() error {
|
||||||
|
return e.origin
|
||||||
|
}
|
425
aerr/client.go
Normal file
425
aerr/client.go
Normal file
@ -0,0 +1,425 @@
|
|||||||
|
package aerr
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewBadRequest will generate an HTTP Error 400.
|
||||||
|
func NewBadRequest() *Error {
|
||||||
|
return &Error{
|
||||||
|
Code: 400,
|
||||||
|
httpCode: 400,
|
||||||
|
Msg: "Bad Request",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewBadRequestf will generate an HTTP Error 400 with a custom message.
|
||||||
|
func NewBadRequestf(format string, a ...any) *Error {
|
||||||
|
aErr := NewBadRequest()
|
||||||
|
return aErr.SetMessage(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewUnauthorized will generate an HTTP Error 401.
|
||||||
|
func NewUnauthorized() *Error {
|
||||||
|
return &Error{
|
||||||
|
Code: 401,
|
||||||
|
httpCode: 401,
|
||||||
|
Msg: "Unauthorized",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewUnauthorizedf will generate an HTTP Error 401 with a custom message.
|
||||||
|
func NewUnauthorizedf(format string, a ...any) *Error {
|
||||||
|
aErr := NewUnauthorized()
|
||||||
|
return aErr.SetMessage(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPaymentRequired will generate an HTTP Error 402.
|
||||||
|
func NewPaymentRequired() *Error {
|
||||||
|
return &Error{
|
||||||
|
Code: 402,
|
||||||
|
httpCode: 402,
|
||||||
|
Msg: "Payment Required",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPaymentRequiredf will generate an HTTP Error 402 with a custom message.
|
||||||
|
func NewPaymentRequiredf(format string, a ...any) *Error {
|
||||||
|
aErr := NewPaymentRequired()
|
||||||
|
return aErr.SetMessage(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewForbidden will generate an HTTP Error 403.
|
||||||
|
func NewForbidden() *Error {
|
||||||
|
return &Error{
|
||||||
|
Code: 403,
|
||||||
|
httpCode: 403,
|
||||||
|
Msg: "Forbidden",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewForbiddenf will generate an HTTP Error 403 with a custom message.
|
||||||
|
func NewForbiddenf(format string, a ...any) *Error {
|
||||||
|
aErr := NewForbidden()
|
||||||
|
return aErr.SetMessage(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewNotFound will generate an HTTP Error 404.
|
||||||
|
func NewNotFound() *Error {
|
||||||
|
return &Error{
|
||||||
|
Code: 404,
|
||||||
|
httpCode: 404,
|
||||||
|
Msg: "Not Found",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewNotFoundf will generate an HTTP Error 404 with a custom message.
|
||||||
|
func NewNotFoundf(format string, a ...any) *Error {
|
||||||
|
aErr := NewNotFound()
|
||||||
|
return aErr.SetMessage(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMethodNotAllowed will generate an HTTP Error 405.
|
||||||
|
func NewMethodNotAllowed() *Error {
|
||||||
|
return &Error{
|
||||||
|
Code: 405,
|
||||||
|
httpCode: 405,
|
||||||
|
Msg: "Method Not Allowed",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMethodNotAllowedf will generate an HTTP Error 405 with a custom message.
|
||||||
|
func NewMethodNotAllowedf(format string, a ...any) *Error {
|
||||||
|
aErr := NewMethodNotAllowed()
|
||||||
|
return aErr.SetMessage(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewNotAcceptable will generate an HTTP Error 406.
|
||||||
|
func NewNotAcceptable() *Error {
|
||||||
|
return &Error{
|
||||||
|
Code: 406,
|
||||||
|
httpCode: 406,
|
||||||
|
Msg: "Not Acceptable",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewNotAcceptablef will generate an HTTP Error 406 with a custom message.
|
||||||
|
func NewNotAcceptablef(format string, a ...any) *Error {
|
||||||
|
aErr := NewNotAcceptable()
|
||||||
|
return aErr.SetMessage(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewProxyAuthenticationRequired will generate an HTTP Error 407.
|
||||||
|
func NewProxyAuthenticationRequired() *Error {
|
||||||
|
return &Error{
|
||||||
|
Code: 407,
|
||||||
|
httpCode: 407,
|
||||||
|
Msg: "Proxy Authentication Required",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewProxyAuthenticationRequiredf will generate an HTTP Error 407 with a custom message.
|
||||||
|
func NewProxyAuthenticationRequiredf(format string, a ...any) *Error {
|
||||||
|
aErr := NewProxyAuthenticationRequired()
|
||||||
|
return aErr.SetMessage(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewRequestTimeout will generate an HTTP Error 408.
|
||||||
|
func NewRequestTimeout() *Error {
|
||||||
|
return &Error{
|
||||||
|
Code: 408,
|
||||||
|
httpCode: 408,
|
||||||
|
Msg: "Request Timeout",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewRequestTimeoutf will generate an HTTP Error 408 with a custom message.
|
||||||
|
func NewRequestTimeoutf(format string, a ...any) *Error {
|
||||||
|
aErr := NewRequestTimeout()
|
||||||
|
return aErr.SetMessage(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewConflict will generate an HTTP Error 409.
|
||||||
|
func NewConflict() *Error {
|
||||||
|
return &Error{
|
||||||
|
Code: 409,
|
||||||
|
httpCode: 409,
|
||||||
|
Msg: "Conflict",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewConflictf will generate an HTTP Error 409 with a custom message.
|
||||||
|
func NewConflictf(format string, a ...any) *Error {
|
||||||
|
aErr := NewConflict()
|
||||||
|
return aErr.SetMessage(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewGone will generate an HTTP Error 410.
|
||||||
|
func NewGone() *Error {
|
||||||
|
return &Error{
|
||||||
|
Code: 410,
|
||||||
|
httpCode: 410,
|
||||||
|
Msg: "Gone",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewGonef will generate an HTTP Error 410 with a custom message.
|
||||||
|
func NewGonef(format string, a ...any) *Error {
|
||||||
|
aErr := NewGone()
|
||||||
|
return aErr.SetMessage(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewLengthRequired will generate an HTTP Error 411.
|
||||||
|
func NewLengthRequired() *Error {
|
||||||
|
return &Error{
|
||||||
|
Code: 411,
|
||||||
|
httpCode: 411,
|
||||||
|
Msg: "Length Required",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewLengthRequiredf will generate an HTTP Error 411 with a custom message.
|
||||||
|
func NewLengthRequiredf(format string, a ...any) *Error {
|
||||||
|
aErr := NewLengthRequired()
|
||||||
|
return aErr.SetMessage(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPreconditionFailed will generate an HTTP Error 412.
|
||||||
|
func NewPreconditionFailed() *Error {
|
||||||
|
return &Error{
|
||||||
|
Code: 412,
|
||||||
|
httpCode: 412,
|
||||||
|
Msg: "Precondition Failed",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPreconditionFailedf will generate an HTTP Error 412 with a custom message.
|
||||||
|
func NewPreconditionFailedf(format string, a ...any) *Error {
|
||||||
|
aErr := NewPreconditionFailed()
|
||||||
|
return aErr.SetMessage(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPayloadTooLarge will generate an HTTP Error 413.
|
||||||
|
func NewPayloadTooLarge() *Error {
|
||||||
|
return &Error{
|
||||||
|
Code: 413,
|
||||||
|
httpCode: 413,
|
||||||
|
Msg: "Payload Too Large",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPayloadTooLargef will generate an HTTP Error 413 with a custom message.
|
||||||
|
func NewPayloadTooLargef(format string, a ...any) *Error {
|
||||||
|
aErr := NewPayloadTooLarge()
|
||||||
|
return aErr.SetMessage(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewURITooLong will generate an HTTP Error 414.
|
||||||
|
func NewURITooLong() *Error {
|
||||||
|
return &Error{
|
||||||
|
Code: 414,
|
||||||
|
httpCode: 414,
|
||||||
|
Msg: "URI Too Long",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewURITooLongf will generate an HTTP Error 414 with a custom message.
|
||||||
|
func NewURITooLongf(format string, a ...any) *Error {
|
||||||
|
aErr := NewURITooLong()
|
||||||
|
return aErr.SetMessage(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewUnsupportedMediaType will generate an HTTP Error 415.
|
||||||
|
func NewUnsupportedMediaType() *Error {
|
||||||
|
return &Error{
|
||||||
|
Code: 415,
|
||||||
|
httpCode: 415,
|
||||||
|
Msg: "Unsupported Media Type",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewUnsupportedMediaTypef will generate an HTTP Error 415 with a custom message.
|
||||||
|
func NewUnsupportedMediaTypef(format string, a ...any) *Error {
|
||||||
|
aErr := NewUnsupportedMediaType()
|
||||||
|
return aErr.SetMessage(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewRangeNotSatisfiable will generate an HTTP Error 416.
|
||||||
|
func NewRangeNotSatisfiable() *Error {
|
||||||
|
return &Error{
|
||||||
|
Code: 416,
|
||||||
|
httpCode: 416,
|
||||||
|
Msg: "Range Not Satisfiable",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewRangeNotSatisfiablef will generate an HTTP Error 416 with a custom message.
|
||||||
|
func NewRangeNotSatisfiablef(format string, a ...any) *Error {
|
||||||
|
aErr := NewRangeNotSatisfiable()
|
||||||
|
return aErr.SetMessage(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewExpectationFailed will generate an HTTP Error 417.
|
||||||
|
func NewExpectationFailed() *Error {
|
||||||
|
return &Error{
|
||||||
|
Code: 417,
|
||||||
|
httpCode: 417,
|
||||||
|
Msg: "Expectation Failed",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewExpectationFailedf will generate an HTTP Error 417 with a custom message.
|
||||||
|
func NewExpectationFailedf(format string, a ...any) *Error {
|
||||||
|
aErr := NewExpectationFailed()
|
||||||
|
return aErr.SetMessage(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMisdirectedRequest will generate an HTTP Error 421.
|
||||||
|
func NewMisdirectedRequest() *Error {
|
||||||
|
return &Error{
|
||||||
|
Code: 421,
|
||||||
|
httpCode: 421,
|
||||||
|
Msg: "Misdirected Request",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMisdirectedRequestf will generate an HTTP Error 421 with a custom message.
|
||||||
|
func NewMisdirectedRequestf(format string, a ...any) *Error {
|
||||||
|
aErr := NewMisdirectedRequest()
|
||||||
|
return aErr.SetMessage(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewUnprocessableEntity will generate an HTTP Error 422.
|
||||||
|
func NewUnprocessableEntity() *Error {
|
||||||
|
return &Error{
|
||||||
|
Code: 422,
|
||||||
|
httpCode: 422,
|
||||||
|
Msg: "Unprocessable Entity",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewUnprocessableEntityf will generate an HTTP Error 422 with a custom message.
|
||||||
|
func NewUnprocessableEntityf(format string, a ...any) *Error {
|
||||||
|
aErr := NewUnprocessableEntity()
|
||||||
|
return aErr.SetMessage(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewLocked will generate an HTTP Error 423.
|
||||||
|
func NewLocked() *Error {
|
||||||
|
return &Error{
|
||||||
|
Code: 423,
|
||||||
|
httpCode: 423,
|
||||||
|
Msg: "Locked",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewLockedf will generate an HTTP Error 423 with a custom message.
|
||||||
|
func NewLockedf(format string, a ...any) *Error {
|
||||||
|
aErr := NewLocked()
|
||||||
|
return aErr.SetMessage(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewFailedDependency will generate an HTTP Error 424.
|
||||||
|
func NewFailedDependency() *Error {
|
||||||
|
return &Error{
|
||||||
|
Code: 424,
|
||||||
|
httpCode: 424,
|
||||||
|
Msg: "Failed Dependency",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewFailedDependencyf will generate an HTTP Error 424 with a custom message.
|
||||||
|
func NewFailedDependencyf(format string, a ...any) *Error {
|
||||||
|
aErr := NewFailedDependency()
|
||||||
|
return aErr.SetMessage(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTooEarly will generate an HTTP Error 425.
|
||||||
|
func NewTooEarly() *Error {
|
||||||
|
return &Error{
|
||||||
|
Code: 425,
|
||||||
|
httpCode: 425,
|
||||||
|
Msg: "Too Early",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTooEarlyf will generate an HTTP Error 425 with a custom message.
|
||||||
|
func NewTooEarlyf(format string, a ...any) *Error {
|
||||||
|
aErr := NewTooEarly()
|
||||||
|
return aErr.SetMessage(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewUpgradeRequired will generate an HTTP Error 426.
|
||||||
|
func NewUpgradeRequired() *Error {
|
||||||
|
return &Error{
|
||||||
|
Code: 426,
|
||||||
|
httpCode: 426,
|
||||||
|
Msg: "Upgrade Required",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewUpgradeRequiredf will generate an HTTP Error 426 with a custom message.
|
||||||
|
func NewUpgradeRequiredf(format string, a ...any) *Error {
|
||||||
|
aErr := NewUpgradeRequired()
|
||||||
|
return aErr.SetMessage(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPreconditionRequired will generate an HTTP Error 428.
|
||||||
|
func NewPreconditionRequired() *Error {
|
||||||
|
return &Error{
|
||||||
|
Code: 428,
|
||||||
|
httpCode: 428,
|
||||||
|
Msg: "Precondition Required",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPreconditionRequiredf will generate an HTTP Error 428 with a custom message.
|
||||||
|
func NewPreconditionRequiredf(format string, a ...any) *Error {
|
||||||
|
aErr := NewPreconditionRequired()
|
||||||
|
return aErr.SetMessage(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTooManyRequests will generate an HTTP Error 429.
|
||||||
|
func NewTooManyRequests() *Error {
|
||||||
|
return &Error{
|
||||||
|
Code: 429,
|
||||||
|
httpCode: 429,
|
||||||
|
Msg: "Too Many Requests",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTooManyRequestsf will generate an HTTP Error 429 with a custom message.
|
||||||
|
func NewTooManyRequestsf(format string, a ...any) *Error {
|
||||||
|
aErr := NewTooManyRequests()
|
||||||
|
return aErr.SetMessage(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewRequestHeaderFieldsTooLarge will generate an HTTP Error 431.
|
||||||
|
func NewRequestHeaderFieldsTooLarge() *Error {
|
||||||
|
return &Error{
|
||||||
|
Code: 431,
|
||||||
|
httpCode: 431,
|
||||||
|
Msg: "Request Header Fields Too Large",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewRequestHeaderFieldsTooLargef will generate an HTTP Error 431 with a custom message.
|
||||||
|
func NewRequestHeaderFieldsTooLargef(format string, a ...any) *Error {
|
||||||
|
aErr := NewRequestHeaderFieldsTooLarge()
|
||||||
|
return aErr.SetMessage(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewUnavailableForLegalReasons will generate an HTTP Error 451.
|
||||||
|
func NewUnavailableForLegalReasons() *Error {
|
||||||
|
return &Error{
|
||||||
|
Code: 451,
|
||||||
|
httpCode: 451,
|
||||||
|
Msg: "Unavailable For Legal Reasons",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewUnavailableForLegalReasonsf will generate an HTTP Error 451 with a custom message.
|
||||||
|
func NewUnavailableForLegalReasonsf(format string, a ...any) *Error {
|
||||||
|
aErr := NewUnavailableForLegalReasons()
|
||||||
|
return aErr.SetMessage(fmt.Sprintf(format, a...))
|
||||||
|
}
|
28
aerr/client.txt
Normal file
28
aerr/client.txt
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
400BadRequest Bad Request
|
||||||
|
401Unauthorized Unauthorized
|
||||||
|
402PaymentRequired Payment Required
|
||||||
|
403Forbidden Forbidden
|
||||||
|
404NotFound Not Found
|
||||||
|
405MethodNotAllowed Method Not Allowed
|
||||||
|
406NotAcceptable Not Acceptable
|
||||||
|
407ProxyAuthenticationRequired Proxy Authentication Required
|
||||||
|
408RequestTimeout Request Timeout
|
||||||
|
409Conflict Conflict
|
||||||
|
410Gone Gone
|
||||||
|
411LengthRequired Length Required
|
||||||
|
412PreconditionFailed Precondition Failed
|
||||||
|
413PayloadTooLarge Payload Too Large
|
||||||
|
414URITooLong URI Too Long
|
||||||
|
415UnsupportedMediaType Unsupported Media Type
|
||||||
|
416RangeNotSatisfiable Range Not Satisfiable
|
||||||
|
417ExpectationFailed Expectation Failed
|
||||||
|
421MisdirectedRequest Misdirected Request
|
||||||
|
422UnprocessableEntity Unprocessable Entity
|
||||||
|
423Locked Locked
|
||||||
|
424FailedDependency Failed Dependency
|
||||||
|
425TooEarly Too Early
|
||||||
|
426UpgradeRequired Upgrade Required
|
||||||
|
428PreconditionRequired Precondition Required
|
||||||
|
429TooManyRequests Too Many Requests
|
||||||
|
431RequestHeaderFieldsTooLarge Request Header Fields Too Large
|
||||||
|
451UnavailableForLegalReasons Unavailable For Legal Reasons
|
18
aerr/note.txt
Normal file
18
aerr/note.txt
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
IN
|
||||||
|
(\d+)([a-zA-Z]+) (.*)
|
||||||
|
|
||||||
|
OUT
|
||||||
|
|
||||||
|
// New$2 will generate an HTTP Error $1.
|
||||||
|
func New$2() *Error {
|
||||||
|
return &Error{
|
||||||
|
Code: $1,
|
||||||
|
httpCode: $1,
|
||||||
|
Msg: "$3",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// New$2f will generate an HTTP Error $1 with a custom message.
|
||||||
|
func New$2f(format string, a ...any) *Error {
|
||||||
|
aErr := New$2()
|
||||||
|
return aErr.SetMessage(fmt.Sprintf(format, a...))
|
||||||
|
}
|
155
aerr/server.go
Normal file
155
aerr/server.go
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
package aerr
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewInternalServerError will generate an HTTP Error 500.
|
||||||
|
func NewInternalServerError() *Error {
|
||||||
|
return &Error{
|
||||||
|
Code: 500,
|
||||||
|
httpCode: 500,
|
||||||
|
Msg: "Internal Server Error",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInternalServerErrorf will generate an HTTP Error 500 with a custom message.
|
||||||
|
func NewInternalServerErrorf(format string, a ...any) *Error {
|
||||||
|
aErr := NewInternalServerError()
|
||||||
|
return aErr.SetMessage(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewNotImplemented will generate an HTTP Error 501.
|
||||||
|
func NewNotImplemented() *Error {
|
||||||
|
return &Error{
|
||||||
|
Code: 501,
|
||||||
|
httpCode: 501,
|
||||||
|
Msg: "Not Implemented",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewNotImplementedf will generate an HTTP Error 501 with a custom message.
|
||||||
|
func NewNotImplementedf(format string, a ...any) *Error {
|
||||||
|
aErr := NewNotImplemented()
|
||||||
|
return aErr.SetMessage(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewBadGateway will generate an HTTP Error 502.
|
||||||
|
func NewBadGateway() *Error {
|
||||||
|
return &Error{
|
||||||
|
Code: 502,
|
||||||
|
httpCode: 502,
|
||||||
|
Msg: "Bad Gateway",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewBadGatewayf will generate an HTTP Error 502 with a custom message.
|
||||||
|
func NewBadGatewayf(format string, a ...any) *Error {
|
||||||
|
aErr := NewBadGateway()
|
||||||
|
return aErr.SetMessage(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewServiceUnavailable will generate an HTTP Error 503.
|
||||||
|
func NewServiceUnavailable() *Error {
|
||||||
|
return &Error{
|
||||||
|
Code: 503,
|
||||||
|
httpCode: 503,
|
||||||
|
Msg: "Service Unavailable",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewServiceUnavailablef will generate an HTTP Error 503 with a custom message.
|
||||||
|
func NewServiceUnavailablef(format string, a ...any) *Error {
|
||||||
|
aErr := NewServiceUnavailable()
|
||||||
|
return aErr.SetMessage(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewGatewayTimeout will generate an HTTP Error 504.
|
||||||
|
func NewGatewayTimeout() *Error {
|
||||||
|
return &Error{
|
||||||
|
Code: 504,
|
||||||
|
httpCode: 504,
|
||||||
|
Msg: "Gateway Timeout",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewGatewayTimeoutf will generate an HTTP Error 504 with a custom message.
|
||||||
|
func NewGatewayTimeoutf(format string, a ...any) *Error {
|
||||||
|
aErr := NewGatewayTimeout()
|
||||||
|
return aErr.SetMessage(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewHTTPVersionNotSupported will generate an HTTP Error 505.
|
||||||
|
func NewHTTPVersionNotSupported() *Error {
|
||||||
|
return &Error{
|
||||||
|
Code: 505,
|
||||||
|
httpCode: 505,
|
||||||
|
Msg: "HTTP Version Not Supported",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewHTTPVersionNotSupportedf will generate an HTTP Error 505 with a custom message.
|
||||||
|
func NewHTTPVersionNotSupportedf(format string, a ...any) *Error {
|
||||||
|
aErr := NewHTTPVersionNotSupported()
|
||||||
|
return aErr.SetMessage(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewVariantAlsoNegotiates will generate an HTTP Error 506.
|
||||||
|
func NewVariantAlsoNegotiates() *Error {
|
||||||
|
return &Error{
|
||||||
|
Code: 506,
|
||||||
|
httpCode: 506,
|
||||||
|
Msg: "Variant Also Negotiates",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewVariantAlsoNegotiatesf will generate an HTTP Error 506 with a custom message.
|
||||||
|
func NewVariantAlsoNegotiatesf(format string, a ...any) *Error {
|
||||||
|
aErr := NewVariantAlsoNegotiates()
|
||||||
|
return aErr.SetMessage(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInsufficientStorage will generate an HTTP Error 507.
|
||||||
|
func NewInsufficientStorage() *Error {
|
||||||
|
return &Error{
|
||||||
|
Code: 507,
|
||||||
|
httpCode: 507,
|
||||||
|
Msg: "Insufficient Storage",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInsufficientStoragef will generate an HTTP Error 507 with a custom message.
|
||||||
|
func NewInsufficientStoragef(format string, a ...any) *Error {
|
||||||
|
aErr := NewInsufficientStorage()
|
||||||
|
return aErr.SetMessage(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewLoopDetected will generate an HTTP Error 508.
|
||||||
|
func NewLoopDetected() *Error {
|
||||||
|
return &Error{
|
||||||
|
Code: 508,
|
||||||
|
httpCode: 508,
|
||||||
|
Msg: "Loop Detected",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewLoopDetectedf will generate an HTTP Error 508 with a custom message.
|
||||||
|
func NewLoopDetectedf(format string, a ...any) *Error {
|
||||||
|
aErr := NewLoopDetected()
|
||||||
|
return aErr.SetMessage(fmt.Sprintf(format, a...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewNotExtended will generate an HTTP Error 510.
|
||||||
|
func NewNotExtended() *Error {
|
||||||
|
return &Error{
|
||||||
|
Code: 510,
|
||||||
|
httpCode: 510,
|
||||||
|
Msg: "Not Extended",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewNotExtendedf will generate an HTTP Error 510 with a custom message.
|
||||||
|
func NewNotExtendedf(format string, a ...any) *Error {
|
||||||
|
aErr := NewNotExtended()
|
||||||
|
return aErr.SetMessage(fmt.Sprintf(format, a...))
|
||||||
|
}
|
10
aerr/server.txt
Normal file
10
aerr/server.txt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
500InternalServerError Internal Server Error
|
||||||
|
501NotImplemented Not Implemented
|
||||||
|
502BadGateway Bad Gateway
|
||||||
|
503ServiceUnavailable Service Unavailable
|
||||||
|
504GatewayTimeout Gateway Timeout
|
||||||
|
505HTTPVersionNotSupported HTTP Version Not Supported
|
||||||
|
506VariantAlsoNegotiates Variant Also Negotiates
|
||||||
|
507InsufficientStorage Insufficient Storage
|
||||||
|
508LoopDetected Loop Detected
|
||||||
|
510NotExtended Not Extended
|
@ -12,7 +12,12 @@ func AddRequestID(ctx context.Context, requestID string) context.Context {
|
|||||||
// GetRequestID retrieve a requestID from the context.
|
// GetRequestID retrieve a requestID from the context.
|
||||||
func GetRequestID(ctx context.Context) *string {
|
func GetRequestID(ctx context.Context) *string {
|
||||||
if requestID := ctx.Value(ContextKey_RequestID); requestID != nil {
|
if requestID := ctx.Value(ContextKey_RequestID); requestID != nil {
|
||||||
return requestID.(*string)
|
requestIDStr, cast := requestID.(string)
|
||||||
|
if !cast {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &requestIDStr
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package ginutils
|
package constant
|
||||||
|
|
||||||
type contextKey string
|
type contextKey string
|
||||||
|
|
||||||
@ -28,4 +28,6 @@ const (
|
|||||||
LogField_Username logField = "username"
|
LogField_Username logField = "username"
|
||||||
LogField_IP logField = "real_ip"
|
LogField_IP logField = "real_ip"
|
||||||
LogField_Duration logField = "duration_ms"
|
LogField_Duration logField = "duration_ms"
|
||||||
|
LogField_Error logField = "error"
|
||||||
|
LogField_ErrorCode logField = "error_code"
|
||||||
)
|
)
|
@ -1,6 +1,8 @@
|
|||||||
package ginutils
|
package ginutils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"git.dev.m-and-m.ovh/mderasse/gocommon/aerr"
|
||||||
|
"git.dev.m-and-m.ovh/mderasse/gocommon/constant"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -8,15 +10,12 @@ import (
|
|||||||
func SimpleTokens(tokens []string, forbiddenHandler gin.HandlerFunc) gin.HandlerFunc {
|
func SimpleTokens(tokens []string, forbiddenHandler gin.HandlerFunc) gin.HandlerFunc {
|
||||||
if forbiddenHandler == nil {
|
if forbiddenHandler == nil {
|
||||||
forbiddenHandler = func(c *gin.Context) {
|
forbiddenHandler = func(c *gin.Context) {
|
||||||
c.AbortWithStatusJSON(403, map[string]string{
|
errorHandler(c, aerr.NewForbidden())
|
||||||
"message": "Forbidden",
|
|
||||||
"debugId": c.GetString(string(ContextKey_RequestID)),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
|
|
||||||
requestToken := c.GetHeader(string(HeaderKey_Token))
|
requestToken := c.GetHeader(string(constant.HeaderKey_Token))
|
||||||
isAuthorized := false
|
isAuthorized := false
|
||||||
for _, key := range tokens {
|
for _, key := range tokens {
|
||||||
if key == requestToken {
|
if key == requestToken {
|
||||||
|
@ -3,6 +3,7 @@ package ginutils
|
|||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"git.dev.m-and-m.ovh/mderasse/gocommon/constant"
|
||||||
"git.dev.m-and-m.ovh/mderasse/gocommon/webserver"
|
"git.dev.m-and-m.ovh/mderasse/gocommon/webserver"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
@ -16,17 +17,17 @@ func Log(l *logrus.Entry) gin.HandlerFunc {
|
|||||||
|
|
||||||
// construct default fields
|
// construct default fields
|
||||||
fields := logrus.Fields{
|
fields := logrus.Fields{
|
||||||
string(LogField_IP): webserver.GetClientIP(c.Request),
|
string(constant.LogField_IP): webserver.GetClientIP(c.Request),
|
||||||
// Request information
|
// Request information
|
||||||
string(LogField_Method): c.Request.Method,
|
string(constant.LogField_Method): c.Request.Method,
|
||||||
string(LogField_CanonPath): c.FullPath(),
|
string(constant.LogField_CanonPath): c.FullPath(),
|
||||||
string(LogField_Path): c.Request.URL.String(),
|
string(constant.LogField_Path): c.Request.URL.String(),
|
||||||
string(LogField_RequestID): c.GetString(string(ContextKey_RequestID)),
|
string(constant.LogField_RequestID): c.GetString(string(constant.ContextKey_RequestID)),
|
||||||
}
|
}
|
||||||
|
|
||||||
// create the logrus entry and add it to gin context
|
// create the logrus entry and add it to gin context
|
||||||
log := l.Logger.WithFields(fields)
|
log := l.Logger.WithFields(fields)
|
||||||
c.Set(string(ContextKey_Logger), log)
|
c.Set(string(constant.ContextKey_Logger), log)
|
||||||
|
|
||||||
log.Info("[start]")
|
log.Info("[start]")
|
||||||
|
|
||||||
@ -34,15 +35,15 @@ func Log(l *logrus.Entry) gin.HandlerFunc {
|
|||||||
|
|
||||||
log.WithFields(
|
log.WithFields(
|
||||||
logrus.Fields{
|
logrus.Fields{
|
||||||
string(LogField_Duration): time.Since(start).Microseconds(),
|
string(constant.LogField_Duration): time.Since(start).Microseconds(),
|
||||||
string(LogField_StatusCode): c.Writer.Status(),
|
string(constant.LogField_StatusCode): c.Writer.Status(),
|
||||||
}).Info("[end]")
|
}).Info("[end]")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetLogger will retrieve a logger instance from gin context and return it or return false.
|
// GetLogger will retrieve a logger instance from gin context and return it or return false.
|
||||||
func GetLogger(c *gin.Context) (*logrus.Entry, bool) {
|
func GetLogger(c *gin.Context) (*logrus.Entry, bool) {
|
||||||
if log, exist := c.Get(string(ContextKey_Logger)); exist {
|
if log, exist := c.Get(string(constant.ContextKey_Logger)); exist {
|
||||||
return log.(*logrus.Entry), true
|
return log.(*logrus.Entry), true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,7 +52,7 @@ func GetLogger(c *gin.Context) (*logrus.Entry, bool) {
|
|||||||
|
|
||||||
// GetLoggerWithField will add a key and value field to the logger, update the gin context, and return the new logger.
|
// GetLoggerWithField will add a key and value field to the logger, update the gin context, and return the new logger.
|
||||||
func GetLoggerWithField(c *gin.Context, key string, value interface{}) *logrus.Entry {
|
func GetLoggerWithField(c *gin.Context, key string, value interface{}) *logrus.Entry {
|
||||||
iLog, exist := c.Get(string(ContextKey_Logger))
|
iLog, exist := c.Get(string(constant.ContextKey_Logger))
|
||||||
if !exist {
|
if !exist {
|
||||||
panic("no logger in context")
|
panic("no logger in context")
|
||||||
}
|
}
|
||||||
@ -62,13 +63,13 @@ func GetLoggerWithField(c *gin.Context, key string, value interface{}) *logrus.E
|
|||||||
}
|
}
|
||||||
|
|
||||||
log = log.WithField(key, value)
|
log = log.WithField(key, value)
|
||||||
c.Set(string(ContextKey_Logger), log)
|
c.Set(string(constant.ContextKey_Logger), log)
|
||||||
return log
|
return log
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetLoggerWithFields will add provided fields to the logger, update the gin context, and return the new logger.
|
// GetLoggerWithFields will add provided fields to the logger, update the gin context, and return the new logger.
|
||||||
func GetLoggerWithFields(c *gin.Context, fields logrus.Fields) *logrus.Entry {
|
func GetLoggerWithFields(c *gin.Context, fields logrus.Fields) *logrus.Entry {
|
||||||
iLog, exist := c.Get(string(ContextKey_Logger))
|
iLog, exist := c.Get(string(constant.ContextKey_Logger))
|
||||||
if !exist {
|
if !exist {
|
||||||
panic("no logger in context")
|
panic("no logger in context")
|
||||||
}
|
}
|
||||||
@ -79,6 +80,6 @@ func GetLoggerWithFields(c *gin.Context, fields logrus.Fields) *logrus.Entry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
log = log.WithFields(fields)
|
log = log.WithFields(fields)
|
||||||
c.Set(string(ContextKey_Logger), log)
|
c.Set(string(constant.ContextKey_Logger), log)
|
||||||
return log
|
return log
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"git.dev.m-and-m.ovh/mderasse/gocommon/aerr"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
@ -15,10 +16,7 @@ import (
|
|||||||
func Recovery(handler gin.HandlerFunc) gin.HandlerFunc {
|
func Recovery(handler gin.HandlerFunc) gin.HandlerFunc {
|
||||||
if handler == nil {
|
if handler == nil {
|
||||||
handler = func(c *gin.Context) {
|
handler = func(c *gin.Context) {
|
||||||
c.AbortWithStatusJSON(500, map[string]string{
|
errorHandler(c, aerr.NewInternalServerError())
|
||||||
"message": "Internal Server Error",
|
|
||||||
"debugId": c.GetString(string(ContextKey_RequestID)),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
@ -37,7 +35,6 @@ func Recovery(handler gin.HandlerFunc) gin.HandlerFunc {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
c.Next()
|
c.Next()
|
||||||
gin.Recovery()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package ginutils
|
package ginutils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"git.dev.m-and-m.ovh/mderasse/gocommon/constant"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
@ -10,16 +11,16 @@ import (
|
|||||||
func RequestID() gin.HandlerFunc {
|
func RequestID() gin.HandlerFunc {
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
|
|
||||||
requestID := c.GetHeader(string(HeaderKey_RequestID))
|
requestID := c.GetHeader(string(constant.HeaderKey_RequestID))
|
||||||
if _, err := uuid.Parse(requestID); err != nil {
|
if _, err := uuid.Parse(requestID); err != nil {
|
||||||
// no request ID or invalid. let's generate a new one
|
// no request ID or invalid. let's generate a new one
|
||||||
requestID = uuid.New().String()
|
requestID = uuid.New().String()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adding to context
|
// Adding to context
|
||||||
c.Set(string(ContextKey_RequestID), requestID)
|
c.Set(string(constant.ContextKey_RequestID), requestID)
|
||||||
// Add request-id to the header before sending the response
|
// Add request-id to the header before sending the response
|
||||||
c.Header(string(HeaderKey_RequestID), requestID)
|
c.Header(string(constant.HeaderKey_RequestID), requestID)
|
||||||
// Let's the next part run
|
// Let's the next part run
|
||||||
c.Next()
|
c.Next()
|
||||||
}
|
}
|
||||||
|
50
ginutils/wrapper.go
Normal file
50
ginutils/wrapper.go
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
package ginutils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"git.dev.m-and-m.ovh/mderasse/gocommon/aerr"
|
||||||
|
"git.dev.m-and-m.ovh/mderasse/gocommon/constant"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
// HandlerFunc represent the type of function expected by the wrapper.
|
||||||
|
type HandlerFunc func(*gin.Context) error
|
||||||
|
|
||||||
|
// HandlerWrapper will wrap a handler to handle error.
|
||||||
|
func HandlerWrapper(h HandlerFunc) gin.HandlerFunc {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
err := h(c)
|
||||||
|
if err != nil {
|
||||||
|
errorHandler(c, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func errorHandler(c *gin.Context, err error) {
|
||||||
|
//nolint: errorlint // Ignore linter to avoid creating useless complexity in the code.
|
||||||
|
switch e := err.(type) {
|
||||||
|
case *aerr.Error:
|
||||||
|
log := GetLoggerWithFields(c, logrus.Fields{
|
||||||
|
string(constant.LogField_Error): e.Error(),
|
||||||
|
string(constant.LogField_ErrorCode): e.Code,
|
||||||
|
})
|
||||||
|
log.Warn("An error occurred")
|
||||||
|
if e.DebugId == "" {
|
||||||
|
e = e.SetDebugID(c.GetString(string(constant.ContextKey_RequestID)))
|
||||||
|
}
|
||||||
|
c.AbortWithStatusJSON(e.HttpCode(), e)
|
||||||
|
default:
|
||||||
|
log := GetLoggerWithFields(c, logrus.Fields{
|
||||||
|
string(constant.LogField_Error): e.Error(),
|
||||||
|
string(constant.LogField_ErrorCode): "500",
|
||||||
|
})
|
||||||
|
log.Warn("An error occurred")
|
||||||
|
c.AbortWithStatusJSON(http.StatusInternalServerError, aerr.Error{
|
||||||
|
Msg: e.Error(),
|
||||||
|
Code: 500,
|
||||||
|
DebugId: c.GetString(string(constant.ContextKey_RequestID)),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
4
go.mod
4
go.mod
@ -6,7 +6,7 @@ require (
|
|||||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2
|
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2
|
||||||
github.com/gemnasium/logrus-graylog-hook/v3 v3.1.1
|
github.com/gemnasium/logrus-graylog-hook/v3 v3.1.1
|
||||||
github.com/gin-gonic/gin v1.9.1
|
github.com/gin-gonic/gin v1.9.1
|
||||||
github.com/google/uuid v1.3.0
|
github.com/google/uuid v1.3.1
|
||||||
github.com/juju/errors v1.0.0
|
github.com/juju/errors v1.0.0
|
||||||
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible
|
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible
|
||||||
github.com/sirupsen/logrus v1.9.3
|
github.com/sirupsen/logrus v1.9.3
|
||||||
@ -27,7 +27,7 @@ require (
|
|||||||
github.com/go-logr/stdr v1.2.2 // indirect
|
github.com/go-logr/stdr v1.2.2 // indirect
|
||||||
github.com/go-playground/locales v0.14.1 // indirect
|
github.com/go-playground/locales v0.14.1 // indirect
|
||||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
github.com/go-playground/validator/v10 v10.15.0 // indirect
|
github.com/go-playground/validator/v10 v10.15.1 // indirect
|
||||||
github.com/goccy/go-json v0.10.2 // indirect
|
github.com/goccy/go-json v0.10.2 // indirect
|
||||||
github.com/jonboulle/clockwork v0.3.0 // indirect
|
github.com/jonboulle/clockwork v0.3.0 // indirect
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
|
8
go.sum
8
go.sum
@ -32,8 +32,8 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o
|
|||||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||||
github.com/go-playground/validator/v10 v10.15.0 h1:nDU5XeOKtB3GEa+uB7GNYwhVKsgjAR7VgKoNB6ryXfw=
|
github.com/go-playground/validator/v10 v10.15.1 h1:BSe8uhN+xQ4r5guV/ywQI4gO59C2raYcGffYWZEjZzM=
|
||||||
github.com/go-playground/validator/v10 v10.15.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
|
github.com/go-playground/validator/v10 v10.15.1/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
|
||||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||||
@ -41,8 +41,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
|||||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
|
||||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/jonboulle/clockwork v0.3.0 h1:9BSCMi8C+0qdApAp4auwX0RkLGUjs956h0EkuQymUhg=
|
github.com/jonboulle/clockwork v0.3.0 h1:9BSCMi8C+0qdApAp4auwX0RkLGUjs956h0EkuQymUhg=
|
||||||
github.com/jonboulle/clockwork v0.3.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
|
github.com/jonboulle/clockwork v0.3.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
|
||||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||||
|
Loading…
Reference in New Issue
Block a user