-
Notifications
You must be signed in to change notification settings - Fork 10
/
code.go
110 lines (95 loc) · 3.68 KB
/
code.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// Copyright (C) 2017 Michael J. Fromberger. All Rights Reserved.
package jrpc2
import (
"context"
"errors"
"fmt"
)
// A Code is an error code included in the JSON-RPC error object.
//
// Code values from and including -32768 to -32000 are reserved for predefined
// JSON-RPC errors. Any code within this range, but not defined explicitly
// below is reserved for future use. The remainder of the space is available
// for application defined errors.
//
// See also: https://www.jsonrpc.org/specification#error_object
type Code int32
func (c Code) String() string {
if s, ok := stdError[c]; ok {
return s
}
return fmt.Sprintf("error code %d", c)
}
// An ErrCoder is a value that can report an error code value.
type ErrCoder interface {
ErrCode() Code
}
// A codeError wraps a Code to satisfy the standard error interface. This
// indirection prevents a Code from accidentally being used as an error value.
// It also satisfies the ErrCoder interface, allowing the code to be recovered.
type codeError Code
// Error satisfies the error interface using the built-in string for the code,
// if one is defined, or else a placeholder that describes the value.
func (c codeError) Error() string { return Code(c).String() }
// ErrCode trivially satisfies the ErrCoder interface.
func (c codeError) ErrCode() Code { return Code(c) }
// Is reports whether err is c or has a code equal to c.
func (c codeError) Is(err error) bool {
v, ok := err.(ErrCoder) // including codeError
return ok && v.ErrCode() == Code(c)
}
// Err converts c to an error value, which is nil for [NoError] and otherwise
// an error value whose code is c and whose text is based on the built-in
// string for c if one exists.
func (c Code) Err() error {
if c == NoError {
return nil
}
return codeError(c)
}
// Error codes from and including -32768 to -32000 are reserved for pre-defined
// errors by the JSON-RPC specification. These constants cover the standard
// codes and implementation-specific codes used by the jrpc2 module.
const (
ParseError Code = -32700 // [std] Invalid JSON received by the server
InvalidRequest Code = -32600 // [std] The JSON sent is not a valid request object
MethodNotFound Code = -32601 // [std] The method does not exist or is unavailable
InvalidParams Code = -32602 // [std] Invalid method parameters
InternalError Code = -32603 // [std] Internal JSON-RPC error
NoError Code = -32099 // Denotes a nil error (used by ErrorCode)
SystemError Code = -32098 // Errors from the operating environment
Cancelled Code = -32097 // Request cancelled (context.Canceled)
DeadlineExceeded Code = -32096 // Request deadline exceeded (context.DeadlineExceeded)
)
var stdError = map[Code]string{
ParseError: "parse error",
InvalidRequest: "invalid request",
MethodNotFound: "method not found",
InvalidParams: "invalid parameters",
InternalError: "internal error",
NoError: "no error (success)",
SystemError: "system error",
Cancelled: "request cancelled",
DeadlineExceeded: "deadline exceeded",
}
// ErrorCode returns a Code to categorize the specified error.
//
// - If err == nil, it returns jrpc2.NoError.
// - If err is (or wraps) an ErrCoder, it returns the reported code value.
// - If err is context.Canceled, it returns jrpc2.Cancelled.
// - If err is context.DeadlineExceeded, it returns jrpc2.DeadlineExceeded.
// - Otherwise it returns jrpc2.SystemError.
func ErrorCode(err error) Code {
if err == nil {
return NoError
}
var c ErrCoder
if errors.As(err, &c) {
return c.ErrCode()
} else if errors.Is(err, context.Canceled) {
return Cancelled
} else if errors.Is(err, context.DeadlineExceeded) {
return DeadlineExceeded
}
return SystemError
}