• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

vocdoni / saas-backend / 17437607990

03 Sep 2025 03:01PM UTC coverage: 58.882% (+0.07%) from 58.81%
17437607990

push

github

altergui
csp: lint unused

5655 of 9604 relevant lines covered (58.88%)

28.98 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

82.47
/errors/errors.go
1
package errors
2

3
import (
4
        "encoding/json"
5
        "fmt"
6
        "net/http"
7
        "runtime"
8

9
        "go.vocdoni.io/dvote/log"
10
)
11

12
// Error is used by handler functions to wrap errors, assigning a unique error code
13
// and also specifying which HTTP Status should be used.
14
type Error struct {
15
        Err        error  // Original error
16
        Code       int    // Error code
17
        HTTPstatus int    // HTTP status code to return
18
        LogLevel   string // Log level for this error (defaults to "debug")
19
        Data       any    // Optional data to include in the error response
20
}
21

22
// MarshalJSON returns a JSON containing Err.Error() and Code. Field HTTPstatus is ignored.
23
//
24
// Example output: {"error":"account not found","code":4003}
25
func (e Error) MarshalJSON() ([]byte, error) {
120✔
26
        // This anon struct is needed to actually include the error string,
120✔
27
        // since it wouldn't be marshaled otherwise. (json.Marshal doesn't call Err.Error())
120✔
28
        return json.Marshal(
120✔
29
                struct {
120✔
30
                        Error string `json:"error"`
120✔
31
                        Code  int    `json:"code"`
120✔
32
                        Data  any    `json:"data,omitempty"`
120✔
33
                }{
120✔
34
                        Error: e.Err.Error(),
120✔
35
                        Code:  e.Code,
120✔
36
                        Data:  e.Data,
120✔
37
                })
120✔
38
}
120✔
39

40
// Error returns the Message contained inside the APIerror
41
func (e Error) Error() string {
116✔
42
        return e.Err.Error()
116✔
43
}
116✔
44

45
// Write serializes a JSON msg using Error.Err and Error.Code
46
// and passes that to http.Error(). It also logs the error with appropriate level.
47
func (e Error) Write(w http.ResponseWriter) {
116✔
48
        msg, err := json.Marshal(e)
116✔
49
        if err != nil {
116✔
50
                log.Warn(err)
×
51
                http.Error(w, "marshal failed", http.StatusInternalServerError)
×
52
                return
×
53
        }
×
54

55
        // Get caller information for better logging
56
        pc, file, line, _ := runtime.Caller(1)
116✔
57
        caller := runtime.FuncForPC(pc).Name()
116✔
58

116✔
59
        // Log the error with appropriate level
116✔
60
        logLevel := e.LogLevel
116✔
61
        if logLevel == "" {
161✔
62
                // Default log level based on HTTP status
45✔
63
                if e.HTTPstatus >= 500 {
45✔
64
                        logLevel = "error"
×
65
                } else {
45✔
66
                        logLevel = "debug"
45✔
67
                }
45✔
68
        }
69

70
        // For 5xx errors, always log with Error level and include internal error details
71
        if e.HTTPstatus >= 500 {
136✔
72
                // For internal errors, log the full error details
20✔
73
                log.Errorw(e.Err, fmt.Sprintf("API error response [%d]: %s (code: %d, caller: %s, file: %s:%d)",
20✔
74
                        e.HTTPstatus, e.Error(), e.Code, caller, file, line))
20✔
75
        } else if log.Level() == log.LogLevelDebug {
212✔
76
                // For 4xx errors, log with debug level
96✔
77
                errMsg := fmt.Sprintf("API error response [%d]: %s (code: %d, caller: %s)",
96✔
78
                        e.HTTPstatus, e.Error(), e.Code, caller)
96✔
79

96✔
80
                switch logLevel {
96✔
81
                case "debug":
45✔
82
                        log.Debugw(errMsg)
45✔
83
                case "info":
51✔
84
                        log.Infow(errMsg)
51✔
85
                case "warn":
×
86
                        log.Warnw(errMsg)
×
87
                default:
×
88
                        log.Debugw(errMsg) // Default to debug level for unknown log levels
×
89
                }
90
        }
91

92
        // Set the content type to JSON
93
        w.Header().Set("Content-Type", "application/json")
116✔
94
        http.Error(w, string(msg), e.HTTPstatus)
116✔
95
}
96

97
// Withf returns a copy of Error with the Sprintf formatted string appended at the end of e.Err
98
func (e Error) Withf(format string, args ...any) Error {
55✔
99
        return Error{
55✔
100
                Err:        fmt.Errorf("%w: %v", e.Err, fmt.Sprintf(format, args...)),
55✔
101
                Code:       e.Code,
55✔
102
                HTTPstatus: e.HTTPstatus,
55✔
103
                LogLevel:   e.LogLevel,
55✔
104
        }
55✔
105
}
55✔
106

107
// With returns a copy of Error with the string appended at the end of e.Err
108
func (e Error) With(s string) Error {
12✔
109
        return Error{
12✔
110
                Err:        fmt.Errorf("%w: %v", e.Err, s),
12✔
111
                Code:       e.Code,
12✔
112
                HTTPstatus: e.HTTPstatus,
12✔
113
                LogLevel:   e.LogLevel,
12✔
114
        }
12✔
115
}
12✔
116

117
// WithErr returns a copy of Error with err.Error() appended at the end of e.Err
118
// The original error is preserved for logging purposes
119
func (e Error) WithErr(err error) Error {
6✔
120
        return Error{
6✔
121
                Err:        fmt.Errorf("%w: %v", e.Err, err.Error()),
6✔
122
                Code:       e.Code,
6✔
123
                HTTPstatus: e.HTTPstatus,
6✔
124
                LogLevel:   e.LogLevel,
6✔
125
        }
6✔
126
}
6✔
127

128
// WithLogLevel returns a copy of Error with the specified log level
129
func (e Error) WithLogLevel(level string) Error {
×
130
        return Error{
×
131
                Err:        e.Err,
×
132
                Code:       e.Code,
×
133
                HTTPstatus: e.HTTPstatus,
×
134
                LogLevel:   level,
×
135
        }
×
136
}
×
137

138
func (e Error) WithData(data any) Error {
3✔
139
        return Error{
3✔
140
                Err:        e.Err,
3✔
141
                Code:       e.Code,
3✔
142
                HTTPstatus: e.HTTPstatus,
3✔
143
                LogLevel:   e.LogLevel,
3✔
144
                Data:       data,
3✔
145
        }
3✔
146
}
3✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc