1
- package error
1
+ // Package specerror implements runtime-spec-specific tooling for
2
+ // tracking RFC 2119 violations.
3
+ package specerror
2
4
3
5
import (
4
- "errors"
5
6
"fmt"
6
7
7
8
"github.com/hashicorp/go-multierror"
9
+ rfc2119 "github.com/opencontainers/runtime-tools/error"
8
10
)
9
11
10
12
const referenceTemplate = "https://github.com/opencontainers/runtime-spec/blob/v%s/%s"
11
13
12
- // SpecErrorCode represents the compliance content.
13
- type SpecErrorCode int
14
+ // Code represents the spec violation, enumerating both
15
+ // configuration violations and runtime violations.
16
+ type Code int
14
17
15
18
const (
16
19
// NonError represents that an input is not an error
17
- NonError SpecErrorCode = iota
20
+ NonError Code = iota
18
21
// NonRFCError represents that an error is not a rfc2119 error
19
22
NonRFCError
20
23
@@ -53,10 +56,19 @@ const (
53
56
)
54
57
55
58
type errorTemplate struct {
56
- Level Level
59
+ Level rfc2119. Level
57
60
Reference func (version string ) (reference string , err error )
58
61
}
59
62
63
+ // Error represents a runtime-spec violation.
64
+ type Error struct {
65
+ // Err holds the RFC 2119 violation.
66
+ Err rfc2119.Error
67
+
68
+ // Code is a matchable holds a Code
69
+ Code Code
70
+ }
71
+
60
72
var (
61
73
containerFormatRef = func (version string ) (reference string , err error ) {
62
74
return fmt .Sprintf (referenceTemplate , version , "bundle.md#container-format" ), nil
@@ -75,62 +87,69 @@ var (
75
87
}
76
88
)
77
89
78
- var ociErrors = map [SpecErrorCode ]errorTemplate {
90
+ var ociErrors = map [Code ]errorTemplate {
79
91
// Bundle.md
80
92
// Container Format
81
- ConfigFileExistence : {Level : Must , Reference : containerFormatRef },
82
- ArtifactsInSingleDir : {Level : Must , Reference : containerFormatRef },
93
+ ConfigFileExistence : {Level : rfc2119 . Must , Reference : containerFormatRef },
94
+ ArtifactsInSingleDir : {Level : rfc2119 . Must , Reference : containerFormatRef },
83
95
84
96
// Config.md
85
97
// Specification Version
86
- SpecVersion : {Level : Must , Reference : specVersionRef },
98
+ SpecVersion : {Level : rfc2119 . Must , Reference : specVersionRef },
87
99
// Root
88
- RootOnNonHyperV : {Level : Required , Reference : rootRef },
89
- RootOnHyperV : {Level : Must , Reference : rootRef },
100
+ RootOnNonHyperV : {Level : rfc2119 . Required , Reference : rootRef },
101
+ RootOnHyperV : {Level : rfc2119 . Must , Reference : rootRef },
90
102
// TODO: add tests for 'PathFormatOnWindows'
91
- PathFormatOnWindows : {Level : Must , Reference : rootRef },
92
- PathName : {Level : Should , Reference : rootRef },
93
- PathExistence : {Level : Must , Reference : rootRef },
94
- ReadonlyFilesystem : {Level : Must , Reference : rootRef },
95
- ReadonlyOnWindows : {Level : Must , Reference : rootRef },
103
+ PathFormatOnWindows : {Level : rfc2119 . Must , Reference : rootRef },
104
+ PathName : {Level : rfc2119 . Should , Reference : rootRef },
105
+ PathExistence : {Level : rfc2119 . Must , Reference : rootRef },
106
+ ReadonlyFilesystem : {Level : rfc2119 . Must , Reference : rootRef },
107
+ ReadonlyOnWindows : {Level : rfc2119 . Must , Reference : rootRef },
96
108
97
109
// Config-Linux.md
98
110
// Default Filesystems
99
- DefaultFilesystems : {Level : Should , Reference : defaultFSRef },
111
+ DefaultFilesystems : {Level : rfc2119 . Should , Reference : defaultFSRef },
100
112
101
113
// Runtime.md
102
114
// Create
103
- CreateWithID : {Level : Must , Reference : runtimeCreateRef },
104
- CreateWithUniqueID : {Level : Must , Reference : runtimeCreateRef },
105
- CreateNewContainer : {Level : Must , Reference : runtimeCreateRef },
115
+ CreateWithID : {Level : rfc2119 .Must , Reference : runtimeCreateRef },
116
+ CreateWithUniqueID : {Level : rfc2119 .Must , Reference : runtimeCreateRef },
117
+ CreateNewContainer : {Level : rfc2119 .Must , Reference : runtimeCreateRef },
118
+ }
119
+
120
+ // Error returns the error message with specification reference.
121
+ func (err * Error ) Error () string {
122
+ return err .Err .Error ()
106
123
}
107
124
108
125
// NewError creates an Error referencing a spec violation. The error
109
- // can be cast to a *runtime-tools.error. Error for extracting
110
- // structured information about the level of the violation and a
111
- // reference to the violated spec condition.
126
+ // can be cast to an * Error for extracting structured information
127
+ // about the level of the violation and a reference to the violated
128
+ // spec condition.
112
129
//
113
130
// A version string (for the version of the spec that was violated)
114
131
// must be set to get a working URL.
115
- func NewError (code SpecErrorCode , msg string , version string ) ( err error ) {
132
+ func NewError (code Code , err error , version string ) error {
116
133
template := ociErrors [code ]
117
- reference , err := template .Reference (version )
118
- if err != nil {
119
- return err
134
+ reference , err2 := template .Reference (version )
135
+ if err2 != nil {
136
+ return err2
120
137
}
121
138
return & Error {
122
- Level : template .Level ,
123
- Reference : reference ,
124
- Err : errors .New (msg ),
125
- ErrCode : int (code ),
139
+ Err : rfc2119.Error {
140
+ Level : template .Level ,
141
+ Reference : reference ,
142
+ Err : err ,
143
+ },
144
+ Code : code ,
126
145
}
127
146
}
128
147
129
148
// FindError finds an error from a source error (multiple error) and
130
- // returns the error code if founded .
149
+ // returns the error code if found .
131
150
// If the source error is nil or empty, return NonError.
132
151
// If the source error is not a multiple error, return NonRFCError.
133
- func FindError (err error , code SpecErrorCode ) SpecErrorCode {
152
+ func FindError (err error , code Code ) Code {
134
153
if err == nil {
135
154
return NonError
136
155
}
@@ -141,7 +160,7 @@ func FindError(err error, code SpecErrorCode) SpecErrorCode {
141
160
}
142
161
for _ , e := range merr .Errors {
143
162
if rfcErr , ok := e .(* Error ); ok {
144
- if rfcErr .ErrCode == int ( code ) {
163
+ if rfcErr .Code == code {
145
164
return code
146
165
}
147
166
}
0 commit comments