Skip to content

Commit d21a9ca

Browse files
committed
Add raw errors payload to errors object
1 parent 5e114a5 commit d21a9ca

File tree

3 files changed

+103
-84
lines changed

3 files changed

+103
-84
lines changed

src/util/validation-error-builder.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,10 @@ export class ValidationErrorBuilder<T extends JSORMBase> {
5454
errorsAccumulator[attribute] = {
5555
title: error.title,
5656
code: error.code,
57-
attribute,
57+
attribute: meta.attribute,
5858
message: meta.message,
59-
fullMessage: attribute === "base" ? meta.message : error.detail
59+
fullMessage: attribute === "base" ? meta.message : error.detail,
60+
rawPayload: error,
6061
} as any
6162
}
6263

src/validation-errors.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export interface IValidationError<T extends JSORMBase> {
77
title: string
88
message: string
99
fullMessage: string
10+
rawPayload: Record<string, any>
1011
}
1112

1213
export class ValidationError<T extends JSORMBase>
@@ -16,6 +17,7 @@ export class ValidationError<T extends JSORMBase>
1617
title: string
1718
message: string
1819
fullMessage: string
20+
rawPayload: Record<string, any>
1921

2022
constructor(options: IValidationError<T>) {
2123
let key: keyof IValidationError<T>

test/integration/validations.test.ts

Lines changed: 98 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -4,85 +4,93 @@ import { tempId } from "../../src/util/temp-id"
44
import { JSORMBase, ModelRecord } from "../../src/model"
55
import { ValidationError } from "../../src/validation-errors"
66

7+
const mockErrors = {
8+
firstName: {
9+
code: "unprocessable_entity",
10+
status: "422",
11+
title: "Validation Error",
12+
detail: "First Name cannot be blank",
13+
meta: { attribute: "first_name", message: "cannot be blank" }
14+
},
15+
lastName: {
16+
code: "unprocessable_entity",
17+
status: "422",
18+
title: "Validation Error",
19+
detail: "Last Name cannot be blank",
20+
meta: { attribute: "last-name", message: "cannot be blank" }
21+
},
22+
bookTitle: {
23+
code: "unprocessable_entity",
24+
status: "422",
25+
title: "Validation Error",
26+
detail: "Title cannot be blank",
27+
meta: {
28+
relationship: {
29+
name: "books",
30+
type: "books",
31+
["temp-id"]: "abc1",
32+
attribute: "title",
33+
message: "cannot be blank"
34+
}
35+
}
36+
},
37+
bookGenreName: {
38+
code: "unprocessable_entity",
39+
status: "422",
40+
title: "Validation Error",
41+
detail: "Name cannot be blank",
42+
meta: {
43+
relationship: {
44+
name: "books",
45+
type: "books",
46+
["temp-id"]: "abc1",
47+
relationship: {
48+
name: "genre",
49+
type: "genres",
50+
id: "1",
51+
attribute: "name",
52+
message: "cannot be blank"
53+
}
54+
}
55+
}
56+
},
57+
bookGenreBase: {
58+
code: "unprocessable_entity",
59+
status: "422",
60+
title: "Validation Error",
61+
detail: "base some error",
62+
meta: {
63+
relationship: {
64+
name: "books",
65+
type: "books",
66+
["temp-id"]: "abc1",
67+
relationship: {
68+
name: "genre",
69+
type: "genres",
70+
id: "1",
71+
attribute: "base",
72+
message: "some error"
73+
}
74+
}
75+
}
76+
}
77+
} as any
78+
779
const resetMocks = () => {
880
fetchMock.restore()
981

82+
let errors = []
83+
84+
for(let key in mockErrors) {
85+
errors.push(mockErrors[key])
86+
}
87+
1088
fetchMock.mock({
1189
matcher: "*",
1290
response: {
1391
status: 422,
1492
body: {
15-
errors: [
16-
{
17-
code: "unprocessable_entity",
18-
status: "422",
19-
title: "Validation Error",
20-
detail: "First Name cannot be blank",
21-
meta: { attribute: "first_name", message: "cannot be blank" }
22-
},
23-
{
24-
code: "unprocessable_entity",
25-
status: "422",
26-
title: "Validation Error",
27-
detail: "Last Name cannot be blank",
28-
meta: { attribute: "last-name", message: "cannot be blank" }
29-
},
30-
{
31-
code: "unprocessable_entity",
32-
status: "422",
33-
title: "Validation Error",
34-
detail: "Title cannot be blank",
35-
meta: {
36-
relationship: {
37-
name: "books",
38-
type: "books",
39-
["temp-id"]: "abc1",
40-
attribute: "title",
41-
message: "cannot be blank"
42-
}
43-
}
44-
},
45-
{
46-
code: "unprocessable_entity",
47-
status: "422",
48-
title: "Validation Error",
49-
detail: "Name cannot be blank",
50-
meta: {
51-
relationship: {
52-
name: "books",
53-
type: "books",
54-
["temp-id"]: "abc1",
55-
relationship: {
56-
name: "genre",
57-
type: "genres",
58-
id: "1",
59-
attribute: "name",
60-
message: "cannot be blank"
61-
}
62-
}
63-
}
64-
},
65-
{
66-
code: "unprocessable_entity",
67-
status: "422",
68-
title: "Validation Error",
69-
detail: "base some error",
70-
meta: {
71-
relationship: {
72-
name: "books",
73-
type: "books",
74-
["temp-id"]: "abc1",
75-
relationship: {
76-
name: "genre",
77-
type: "genres",
78-
id: "1",
79-
attribute: "base",
80-
message: "some error"
81-
}
82-
}
83-
}
84-
}
85-
]
93+
errors
8694
}
8795
}
8896
})
@@ -120,18 +128,20 @@ describe("validations", () => {
120128
expect(isSuccess).to.eq(false)
121129
expect(instance.errors).to.deep.equal({
122130
firstName: {
123-
attribute: "firstName",
131+
attribute: "first_name",
124132
code: "unprocessable_entity",
125133
fullMessage: "First Name cannot be blank",
126134
message: "cannot be blank",
127-
title: "Validation Error"
135+
title: "Validation Error",
136+
rawPayload: mockErrors.firstName,
128137
},
129138
lastName: {
130-
attribute: "lastName",
139+
attribute: "last-name",
131140
code: "unprocessable_entity",
132141
fullMessage: "Last Name cannot be blank",
133142
message: "cannot be blank",
134-
title: "Validation Error"
143+
title: "Validation Error",
144+
rawPayload: mockErrors.lastName,
135145
}
136146
})
137147
})
@@ -154,14 +164,16 @@ describe("validations", () => {
154164
code: "unprocessable_entity",
155165
fullMessage: "First Name cannot be blank",
156166
message: "cannot be blank",
157-
title: "Validation Error"
167+
title: "Validation Error",
168+
rawPayload: mockErrors.firstName,
158169
},
159170
last_name: {
160-
attribute: "last_name",
171+
attribute: "last-name",
161172
code: "unprocessable_entity",
162173
fullMessage: "Last Name cannot be blank",
163174
message: "cannot be blank",
164-
title: "Validation Error"
175+
title: "Validation Error",
176+
rawPayload: mockErrors.lastName,
165177
}
166178
})
167179
})
@@ -199,7 +211,8 @@ describe("validations", () => {
199211
attribute: "nilly",
200212
code: "required",
201213
message: "is required",
202-
fullMessage: "Nilly is required"
214+
fullMessage: "Nilly is required",
215+
rawPayload: { foo: 'bar' }
203216
}
204217
}
205218

@@ -233,7 +246,8 @@ describe("validations", () => {
233246
attribute: "title",
234247
code: "unprocessable_entity",
235248
message: "cannot be blank",
236-
fullMessage: "Title cannot be blank"
249+
fullMessage: "Title cannot be blank",
250+
rawPayload: mockErrors.bookTitle,
237251
}
238252
})
239253
})
@@ -251,14 +265,16 @@ describe("validations", () => {
251265
attribute: "name",
252266
code: "unprocessable_entity",
253267
fullMessage: "Name cannot be blank",
254-
message: "cannot be blank"
268+
message: "cannot be blank",
269+
rawPayload: mockErrors.bookGenreName,
255270
},
256271
base: {
257272
title: "Validation Error",
258273
attribute: "base",
259274
code: "unprocessable_entity",
260275
fullMessage: "some error",
261-
message: "some error"
276+
message: "some error",
277+
rawPayload: mockErrors.bookGenreBase,
262278
}
263279
})
264280
})

0 commit comments

Comments
 (0)