mirror of
https://github.com/lukaszraczylo/gohoarder.git
synced 2026-06-05 22:53:53 +00:00
116 lines
2.6 KiB
Go
116 lines
2.6 KiB
Go
package errors
|
|
|
|
import (
|
|
"fmt"
|
|
)
|
|
|
|
// Error represents a structured error with code and details
|
|
type Error struct {
|
|
Code string `json:"code"`
|
|
Message string `json:"message"`
|
|
Details interface{} `json:"details,omitempty"`
|
|
Trace []string `json:"trace,omitempty"`
|
|
Cause error `json:"-"` // Internal cause, not serialized
|
|
}
|
|
|
|
// Error implements the error interface
|
|
func (e *Error) Error() string {
|
|
if e.Cause != nil {
|
|
return fmt.Sprintf("%s: %s (caused by: %v)", e.Code, e.Message, e.Cause)
|
|
}
|
|
return fmt.Sprintf("%s: %s", e.Code, e.Message)
|
|
}
|
|
|
|
// Unwrap returns the cause for errors.Is/As support
|
|
func (e *Error) Unwrap() error {
|
|
return e.Cause
|
|
}
|
|
|
|
// New creates a new error with the given code and message
|
|
func New(code, message string) *Error {
|
|
return &Error{
|
|
Code: code,
|
|
Message: message,
|
|
}
|
|
}
|
|
|
|
// Newf creates a new error with formatted message
|
|
func Newf(code, format string, args ...interface{}) *Error {
|
|
return &Error{
|
|
Code: code,
|
|
Message: fmt.Sprintf(format, args...),
|
|
}
|
|
}
|
|
|
|
// WithDetails adds details to the error
|
|
func (e *Error) WithDetails(details interface{}) *Error {
|
|
e.Details = details
|
|
return e
|
|
}
|
|
|
|
// WithTrace adds stack trace to the error
|
|
func (e *Error) WithTrace(trace []string) *Error {
|
|
e.Trace = trace
|
|
return e
|
|
}
|
|
|
|
// WithCause adds an underlying cause to the error
|
|
func (e *Error) WithCause(cause error) *Error {
|
|
e.Cause = cause
|
|
return e
|
|
}
|
|
|
|
// Wrap wraps an existing error with a new code and message
|
|
func Wrap(err error, code, message string) *Error {
|
|
return &Error{
|
|
Code: code,
|
|
Message: message,
|
|
Cause: err,
|
|
}
|
|
}
|
|
|
|
// Wrapf wraps an existing error with formatted message
|
|
func Wrapf(err error, code, format string, args ...interface{}) *Error {
|
|
return &Error{
|
|
Code: code,
|
|
Message: fmt.Sprintf(format, args...),
|
|
Cause: err,
|
|
}
|
|
}
|
|
|
|
// Common error constructors
|
|
func BadRequest(message string) *Error {
|
|
return New(ErrCodeBadRequest, message)
|
|
}
|
|
|
|
func Unauthorized(message string) *Error {
|
|
return New(ErrCodeUnauthorized, message)
|
|
}
|
|
|
|
func Forbidden(message string) *Error {
|
|
return New(ErrCodeForbidden, message)
|
|
}
|
|
|
|
func NotFound(message string) *Error {
|
|
return New(ErrCodeNotFound, message)
|
|
}
|
|
|
|
func InternalServer(message string) *Error {
|
|
return New(ErrCodeInternalServer, message)
|
|
}
|
|
|
|
func PackageNotFound(name, version string) *Error {
|
|
return New(ErrCodePackageNotFound, fmt.Sprintf("Package %s@%s not found", name, version)).
|
|
WithDetails(map[string]string{
|
|
"package": name,
|
|
"version": version,
|
|
})
|
|
}
|
|
|
|
func QuotaExceeded(limit int64) *Error {
|
|
return New(ErrCodeQuotaExceeded, "Storage quota exceeded").
|
|
WithDetails(map[string]interface{}{
|
|
"limit_bytes": limit,
|
|
})
|
|
}
|