forked from santhosh-tekuri/jsonschema
-
Notifications
You must be signed in to change notification settings - Fork 6
/
errors.go
136 lines (115 loc) · 3.6 KB
/
errors.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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// Copyright 2017 Santhosh Kumar Tekuri. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package jsonschema
import (
"fmt"
"strings"
)
// InvalidJSONTypeError is the error type returned by ValidateInteface.
// this tells that specified go object is not valid jsonType.
type InvalidJSONTypeError string
func (e InvalidJSONTypeError) Error() string {
return fmt.Sprintf("invalid jsonType: %s", string(e))
}
// SchemaError is the error type returned by Compile.
type SchemaError struct {
// SchemaURL is the url to json-schema that filed to compile.
// This is helpful, if your schema refers to external schemas
SchemaURL string
// Err is the error that occurred during compilation.
// It could be ValidationError, because compilation validates
// given schema against the json meta-schema
Err error
}
func (se *SchemaError) Error() string {
return fmt.Sprintf("json-schema %q compilation failed. Reason:\n%s", se.SchemaURL, se.Err)
}
// ValidationError is the error type returned by Validate.
type ValidationError struct {
// Message describes error
Message string
// InstancePtr is json-pointer which refers to json-fragment in json instance
// that is not valid
InstancePtr string
// SchemaURL is the url to json-schema against which validation failed.
// This is helpful, if your schema refers to external schemas
SchemaURL string
// SchemaPtr is json-pointer which refers to json-fragment in json schema
// that failed to satisfy
SchemaPtr string
// Context represents error context for this specific validation error.
Context ValidationErrorContext
// Causes details the nested validation errors
Causes []*ValidationError
}
func (ve *ValidationError) add(causes ...error) error {
for _, cause := range causes {
_ = addContext(ve.InstancePtr, ve.SchemaPtr, cause)
ve.Causes = append(ve.Causes, cause.(*ValidationError))
}
return ve
}
// MessageFmt returns the Message formatted, but does not include child Cause messages.
func (ve *ValidationError) MessageFmt() string {
return fmt.Sprintf("I[%s] S[%s] %s", ve.InstancePtr, ve.SchemaPtr, ve.Message)
}
func (ve *ValidationError) Error() string {
msg := ve.MessageFmt()
for _, c := range ve.Causes {
for _, line := range strings.Split(c.Error(), "\n") {
msg += "\n " + line
}
}
return msg
}
func validationError(schemaPtr string, format string, a ...interface{}) *ValidationError {
return &ValidationError{fmt.Sprintf(format, a...), "", "", schemaPtr, nil, nil}
}
func addContext(instancePtr, schemaPtr string, err error) error {
ve := err.(*ValidationError)
ve.InstancePtr = joinPtr(instancePtr, ve.InstancePtr)
if len(ve.SchemaURL) == 0 {
ve.SchemaPtr = joinPtr(schemaPtr, ve.SchemaPtr)
}
if ve.Context != nil {
ve.Context.AddContext(instancePtr, ve.SchemaPtr)
}
for _, cause := range ve.Causes {
_ = addContext(instancePtr, schemaPtr, cause)
}
return ve
}
func finishSchemaContext(err error, s *Schema) {
ve := err.(*ValidationError)
if len(ve.SchemaURL) == 0 {
ve.SchemaURL = s.URL
ve.SchemaPtr = joinPtr(s.Ptr, ve.SchemaPtr)
for _, cause := range ve.Causes {
finishSchemaContext(cause, s)
}
}
}
func finishInstanceContext(err error) {
ve := err.(*ValidationError)
if len(ve.InstancePtr) == 0 {
ve.InstancePtr = "#"
} else {
ve.InstancePtr = "#/" + ve.InstancePtr
}
if ve.Context != nil {
ve.Context.FinishInstanceContext()
}
for _, cause := range ve.Causes {
finishInstanceContext(cause)
}
}
func joinPtr(ptr1, ptr2 string) string {
if len(ptr1) == 0 {
return ptr2
}
if len(ptr2) == 0 {
return ptr1
}
return ptr1 + "/" + ptr2
}