api: response error in json instead of html for better rendering flexibility

This commit is contained in:
yusing
2025-01-29 11:50:08 +08:00
parent 4ad6257dab
commit d9b6b82f07
3 changed files with 43 additions and 10 deletions

View File

@@ -1,6 +1,7 @@
package err
import (
"encoding/json"
"errors"
"fmt"
)
@@ -46,3 +47,18 @@ func (err baseError) Withf(format string, args ...any) Error {
func (err *baseError) Error() string {
return err.Err.Error()
}
// MarshalJSON implements the json.Marshaler interface.
func (err *baseError) MarshalJSON() ([]byte, error) {
//nolint:errorlint
switch err := err.Err.(type) {
case Error, *withSubject:
return json.Marshal(err)
case json.Marshaler:
return err.MarshalJSON()
case interface{ MarshalText() ([]byte, error) }:
return err.MarshalText()
default:
return json.Marshal(err.Error())
}
}

View File

@@ -1,6 +1,7 @@
package err
import (
"encoding/json"
"strings"
"github.com/yusing/go-proxy/internal/utils/strutils/ansi"
@@ -8,8 +9,8 @@ import (
//nolint:errname
type withSubject struct {
Subjects []string `json:"subjects"`
Err error `json:"err"`
Subjects []string
Err error
pendingSubject string
}
@@ -74,7 +75,7 @@ func (err *withSubject) Error() string {
for _, s := range err.Subjects {
size += len(s)
}
sb.Grow(size + 2 + n*len(subjectSep) + len(errStr))
sb.Grow(size + 2 + n*len(subjectSep) + len(errStr) + len(highlight("")))
for i := n - 1; i > 0; i-- {
sb.WriteString(err.Subjects[i])
@@ -85,3 +86,20 @@ func (err *withSubject) Error() string {
sb.WriteString(errStr)
return sb.String()
}
// MarshalJSON implements the json.Marshaler interface.
func (err *withSubject) MarshalJSON() ([]byte, error) {
subjects := make([]string, len(err.Subjects))
for i, s := range err.Subjects {
subjects[len(err.Subjects)-i-1] = s
}
reversed := struct {
Subjects []string `json:"subjects"`
Err error `json:"err"`
}{
Subjects: subjects,
Err: err.Err,
}
return json.Marshal(reversed)
}