1
0
mirror of https://github.com/imgproxy/imgproxy.git synced 2025-12-23 22:11:10 +02:00
Files
imgproxy/errctx/context.go
Sergei Aleksandrovich e33254005d Refactored errors (#1578)
* Refactored errors

* Make monitoring and errorreport accept `errctx.Error` instead of `error`

* Add server.Error; Remove category from errctx; Make HTTP handlers respond with *server.Error

* Remove stackSkip from errctx.Wrap; Add errctx.WrapWithStackSkip
2025-11-20 01:26:21 +06:00

93 lines
1.8 KiB
Go

package errctx
import (
"fmt"
"net/http"
"runtime"
"strings"
)
type ErrorContext struct {
prefix string
statusCode int
publicMsg string
shouldReport bool
stack []uintptr
}
func newErrorContext(stackSkip int, opts ...Option) *ErrorContext {
ec := &ErrorContext{
statusCode: http.StatusInternalServerError,
publicMsg: "Internal error",
shouldReport: true,
stack: callers(stackSkip + 1),
}
return ec.applyOptions(opts...)
}
func (ec *ErrorContext) applyOptions(opts ...Option) *ErrorContext {
for _, opt := range opts {
opt(ec)
}
return ec
}
func (ec *ErrorContext) CloneErrorContext(opts ...Option) *ErrorContext {
newEc := *ec
return newEc.applyOptions(opts...)
}
func (ec *ErrorContext) StatusCode() int {
if ec.statusCode <= 0 {
return 500
}
return ec.statusCode
}
func (ec *ErrorContext) PublicMessage() string {
if len(ec.publicMsg) == 0 {
return "Internal error"
}
return ec.publicMsg
}
func (ec *ErrorContext) ShouldReport() bool {
return ec.shouldReport
}
// StackTrace returns the stack trace associated with the error.
func (ec *ErrorContext) StackTrace() []uintptr {
return ec.stack
}
// Callers returns the stack trace associated with the error.
func (ec *ErrorContext) Callers() []uintptr {
return ec.stack
}
// FormatStack formats the stack trace into a single string.
func (ec *ErrorContext) FormatStack() string {
lines := make([]string, len(ec.stack))
for i, pc := range ec.stack {
f := runtime.FuncForPC(pc)
file, line := f.FileLine(pc)
lines[i] = fmt.Sprintf("%s:%d %s", file, line, f.Name())
}
return strings.Join(lines, "\n")
}
// callers returns the stack trace, skipping the specified number of frames.
func callers(skip int) []uintptr {
stack := make([]uintptr, 10)
n := runtime.Callers(skip+2, stack)
return stack[:n]
}