Skip to content

Commit fe59894

Browse files
committed
🔧 fix: ValidationError.detail only handle custom error
1 parent b99a587 commit fe59894

File tree

6 files changed

+92
-36
lines changed

6 files changed

+92
-36
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# 1.3.15 - 21 Aug 2025
2+
Bug fix:
3+
- ValidationError.detail only handle custom error
4+
15
# 1.3.14 - 21 Aug 2025
26
Improvement:
37
- custom error on production mode

example/a.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ new Elysia()
77
.post('/', () => 'Hello World!', {
88
body: t.Object({
99
x: t.Number({
10-
error: 'x must be a number',
11-
})
10+
error: 'x must be a number'
11+
}),
1212
})
1313
})
1414
.listen(3000)

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "elysia",
33
"description": "Ergonomic Framework for Human",
4-
"version": "1.3.14",
4+
"version": "1.3.15",
55
"author": {
66
"name": "saltyAom",
77
"url": "https://github.com/SaltyAom",

src/error.ts

Lines changed: 52 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,8 @@ export class ValidationError extends Error {
249249
status = 422
250250

251251
valueError?: ValueError
252+
expected?: unknown
253+
customError?: string
252254

253255
constructor(
254256
public type: string,
@@ -271,6 +273,24 @@ export class ValidationError extends Error {
271273

272274
const accessor = error?.path || 'root'
273275

276+
// @ts-ignore private field
277+
const schema = validator?.schema ?? validator
278+
279+
let expected
280+
281+
if (!isProduction) {
282+
try {
283+
expected = Value.Create(schema)
284+
} catch (error) {
285+
expected = {
286+
type: 'Could not create expected value',
287+
// @ts-expect-error
288+
message: error?.message,
289+
error
290+
}
291+
}
292+
}
293+
274294
const customError =
275295
error?.schema?.message || error?.schema?.error !== undefined
276296
? typeof error.schema.error === 'function'
@@ -285,15 +305,24 @@ export class ValidationError extends Error {
285305
type: 'validation',
286306
on: type,
287307
value,
288-
summary: mapValueError(error).summary,
289308
property: accessor,
290309
message: error?.message,
310+
summary: mapValueError(error).summary,
291311
found: value,
292-
get errors() {
293-
return [
294-
...validator?.Errors(value)
295-
].map(mapValueError)
296-
}
312+
expected,
313+
errors:
314+
'Errors' in validator
315+
? [
316+
...validator.Errors(
317+
value
318+
)
319+
].map(mapValueError)
320+
: [
321+
...Value.Errors(
322+
validator,
323+
value
324+
)
325+
].map(mapValueError)
297326
},
298327
validator
299328
)
@@ -314,36 +343,21 @@ export class ValidationError extends Error {
314343
found: value
315344
})
316345
} else {
317-
// @ts-ignore private field
318-
const schema = validator?.schema ?? validator
319-
const errors =
320-
'Errors' in validator
321-
? [...validator.Errors(value)].map(mapValueError)
322-
: [...Value.Errors(validator, value)].map(mapValueError)
323-
324-
let expected
325-
326-
try {
327-
expected = Value.Create(schema)
328-
} catch (error) {
329-
expected = {
330-
type: 'Could not create expected value',
331-
// @ts-expect-error
332-
message: error?.message,
333-
error
334-
}
335-
}
336-
337346
message = JSON.stringify(
338347
{
339348
type: 'validation',
340349
on: type,
341-
summary: mapValueError(error).summary,
342350
property: accessor,
343351
message: error?.message,
352+
summary: mapValueError(error).summary,
344353
expected,
345354
found: value,
346-
errors
355+
errors:
356+
'Errors' in validator
357+
? [...validator.Errors(value)].map(mapValueError)
358+
: [...Value.Errors(validator, value)].map(
359+
mapValueError
360+
)
347361
},
348362
null,
349363
2
@@ -353,6 +367,8 @@ export class ValidationError extends Error {
353367
super(message)
354368

355369
this.valueError = error
370+
this.expected = expected
371+
this.customError = customError
356372

357373
Object.setPrototypeOf(this, ValidationError.prototype)
358374
}
@@ -411,9 +427,13 @@ export class ValidationError extends Error {
411427
* })
412428
* ```
413429
*/
414-
detail(message: string) {
430+
detail(message: unknown) {
431+
if (!this.customError) return this.message
432+
415433
const validator = this.validator
416434
const value = this.value
435+
const expected = this.expected
436+
const errors = this.all
417437

418438
return isProduction
419439
? {
@@ -425,13 +445,12 @@ export class ValidationError extends Error {
425445
: {
426446
type: 'validation',
427447
on: this.type,
448+
property: this.valueError?.path || 'root',
428449
message,
429450
summary: mapValueError(this.valueError).summary,
430-
property: this.valueError?.path || 'root',
431451
found: value,
432-
get errors() {
433-
return [...validator.Errors(value)].map(mapValueError)
434-
}
452+
expected,
453+
errors
435454
}
436455
}
437456
}

src/type-system/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,11 @@ export type ElysiaTypeCustomErrorCallback = (
181181
* (omitted on production)
182182
*/
183183
message?: string
184+
/**
185+
* Expected value
186+
* (omitted on production)
187+
*/
188+
expected?: unknown
184189
/**
185190
* Array of validation errors
186191
* (omitted on production)

test/lifecycle/error.test.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,4 +423,32 @@ describe('error', () => {
423423
expect(value.type).toBe('validation')
424424
expect(value.message).toBe('x must be a number')
425425
})
426+
427+
it('ValidationError.detail only handle custom error', async () => {
428+
const app = new Elysia()
429+
.onError(({ error, code }) => {
430+
if (code === 'VALIDATION') return error.detail(error.message)
431+
})
432+
.post('/', () => 'Hello World!', {
433+
body: t.Object({
434+
x: t.Number()
435+
})
436+
})
437+
438+
const response = await app.handle(
439+
new Request('http://localhost', {
440+
method: 'POST',
441+
body: JSON.stringify({ x: 'hi!' }),
442+
headers: {
443+
'Content-Type': 'application/json'
444+
}
445+
})
446+
)
447+
448+
expect(response.status).toBe(422)
449+
450+
const value = (await response.json()) as Record<string, unknown>
451+
expect(value.type).toBe('validation')
452+
expect(value.message).not.toStartWith('{')
453+
})
426454
})

0 commit comments

Comments
 (0)