cloudflare/pint

Public

mirrored from https://github.com/cloudflare/pintAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v0.33.0

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

internal/promapi/errors.go

109lines · modeblame

e6a0531fLukasz Mierzwa4 years ago1package promapi
2
3import (
4296ae4fLukasz Mierzwa4 years ago4"context"
2ea75469Lukasz Mierzwa3 years ago5"encoding/json"
e6a0531fLukasz Mierzwa4 years ago6"errors"
4296ae4fLukasz Mierzwa4 years ago7"fmt"
e6a0531fLukasz Mierzwa4 years ago8"net"
f393e060Lukasz Mierzwa3 years ago9"net/http"
e6a0531fLukasz Mierzwa4 years ago10"syscall"
11
12v1 "github.com/prometheus/client_golang/api/prometheus/v1"
2ea75469Lukasz Mierzwa3 years ago13"github.com/prymitive/current"
e6a0531fLukasz Mierzwa4 years ago14)
15
16func IsUnavailableError(err error) bool {
f393e060Lukasz Mierzwa3 years ago17var e1 APIError
18if ok := errors.As(err, &e1); ok {
19return e1.ErrorType == v1.ErrServer
e6a0531fLukasz Mierzwa4 years ago20}
21
22return true
23}
24
0483c1c0Lukasz Mierzwa4 years ago25type APIError struct {
26Status string `json:"status"`
27ErrorType v1.ErrorType `json:"errorType"`
f393e060Lukasz Mierzwa3 years ago28Err string `json:"error"`
29}
30
31func (e APIError) Error() string {
32return e.Err
33}
34
35const (
36ErrUnknown v1.ErrorType = "unknown"
37ErrJSONStream v1.ErrorType = "json_stream"
38)
39
40func decodeErrorType(s string) v1.ErrorType {
41switch s {
42case string(v1.ErrBadData):
43return v1.ErrBadData
44case string(v1.ErrTimeout):
45return v1.ErrTimeout
46case string(v1.ErrCanceled):
47return v1.ErrCanceled
48case string(v1.ErrExec):
49return v1.ErrExec
50case string(v1.ErrBadResponse):
51return v1.ErrBadResponse
52case string(v1.ErrServer):
53return v1.ErrServer
54case string(v1.ErrClient):
55return v1.ErrClient
56default:
57return ErrUnknown
58}
0483c1c0Lukasz Mierzwa4 years ago59}
60
4296ae4fLukasz Mierzwa4 years ago61func decodeError(err error) string {
62if errors.Is(err, context.Canceled) {
63return context.Canceled.Error()
64}
65
e6a0531fLukasz Mierzwa4 years ago66if errors.Is(err, syscall.ECONNREFUSED) {
4296ae4fLukasz Mierzwa4 years ago67return "connection refused"
e6a0531fLukasz Mierzwa4 years ago68}
69
70var neterr net.Error
71if ok := errors.As(err, &neterr); ok && neterr.Timeout() {
4296ae4fLukasz Mierzwa4 years ago72return "connection timeout"
e6a0531fLukasz Mierzwa4 years ago73}
74
f393e060Lukasz Mierzwa3 years ago75var e1 APIError
76if ok := errors.As(err, &e1); ok {
77return fmt.Sprintf("%s: %s", e1.ErrorType, e1.Err)
e6a0531fLukasz Mierzwa4 years ago78}
79
4296ae4fLukasz Mierzwa4 years ago80return err.Error()
e6a0531fLukasz Mierzwa4 years ago81}
f393e060Lukasz Mierzwa3 years ago82
83func tryDecodingAPIError(resp *http.Response) error {
2ea75469Lukasz Mierzwa3 years ago84var status, errType, errText string
85decoder := current.Object(
86current.Key("status", current.Value(func(s string, isNil bool) {
87status = s
88})),
89current.Key("error", current.Value(func(s string, isNil bool) {
90errText = s
91})),
92current.Key("errorType", current.Value(func(s string, isNil bool) {
93errType = s
94})),
95)
96
97dec := json.NewDecoder(resp.Body)
98if err := decoder.Stream(dec); err != nil {
99switch resp.StatusCode / 100 {
100case 4:
101return APIError{Status: "error", ErrorType: v1.ErrClient, Err: fmt.Sprintf("client error: %d", resp.StatusCode)}
102case 5:
103return APIError{Status: "error", ErrorType: v1.ErrServer, Err: fmt.Sprintf("server error: %d", resp.StatusCode)}
104}
105return APIError{Status: "error", ErrorType: v1.ErrBadResponse, Err: fmt.Sprintf("bad response code: %d", resp.StatusCode)}
f393e060Lukasz Mierzwa3 years ago106}
107
2ea75469Lukasz Mierzwa3 years ago108return APIError{Status: status, ErrorType: decodeErrorType(errType), Err: errText}
f393e060Lukasz Mierzwa3 years ago109}