File tree Expand file tree Collapse file tree 4 files changed +84
-4
lines changed Expand file tree Collapse file tree 4 files changed +84
-4
lines changed Original file line number Diff line number Diff line change @@ -13,6 +13,7 @@ import type {
1313} from 'aws-lambda'
1414import { aProblem } from './aProblem.js'
1515import { ValidationFailedError } from './validateInput.js'
16+ import { ResponseValidationFailedError } from './validateResponse.js'
1617
1718export class ProblemDetailError extends Error {
1819 public readonly problem : Static < typeof ProblemDetail >
@@ -40,6 +41,12 @@ export const problemResponse = (): MiddlewareObj<
4041 status : HttpStatusCode . BAD_REQUEST ,
4142 detail : formatTypeBoxErrors ( req . error . errors ) ,
4243 } )
44+ } else if ( req . error instanceof ResponseValidationFailedError ) {
45+ req . response = aProblem ( {
46+ title : 'Response validation failed' ,
47+ status : HttpStatusCode . INTERNAL_SERVER_ERROR ,
48+ detail : formatTypeBoxErrors ( req . error . errors ) ,
49+ } )
4350 } else if ( req . error instanceof ProblemDetailError ) {
4451 req . response = aProblem ( req . error . problem )
4552 } else {
Original file line number Diff line number Diff line change 1- import { validateWithTypeBox } from '@hello.nrfcloud.com/proto'
1+ import {
2+ formatTypeBoxErrors ,
3+ validateWithTypeBox ,
4+ } from '@hello.nrfcloud.com/proto'
25import type { MiddlewareObj } from '@middy/core'
36import type { Static , TSchema } from '@sinclair/typebox'
47import type { ValueError } from '@sinclair/typebox/compiler'
@@ -11,8 +14,8 @@ import { tryAsJSON } from './tryAsJSON.js'
1114
1215export class ValidationFailedError extends Error {
1316 public readonly errors : ValueError [ ]
14- constructor ( errors : ValueError [ ] ) {
15- super ( 'Validation failed' )
17+ constructor ( errors : ValueError [ ] , message = 'Validation failed' ) {
18+ super ( message )
1619 this . errors = errors
1720 this . name = 'ValidationFailedError'
1821 }
@@ -50,7 +53,10 @@ export const validateInput = <Schema extends TSchema>(
5053 console . debug (
5154 `[validateInput]` ,
5255 `Input not valid` ,
53- JSON . stringify ( maybeValidInput . errors ) ,
56+ JSON . stringify ( {
57+ input,
58+ errors : formatTypeBoxErrors ( maybeValidInput . errors ) ,
59+ } ) ,
5460 )
5561 throw new ValidationFailedError ( maybeValidInput . errors )
5662 }
Original file line number Diff line number Diff line change 1+ import middy from '@middy/core'
2+ import { Type } from '@sinclair/typebox'
3+ import type { Context } from 'aws-lambda'
4+ import assert from 'node:assert'
5+ import { describe , it } from 'node:test'
6+ import {
7+ ResponseValidationFailedError ,
8+ validateResponse ,
9+ } from './validateResponse.js'
10+
11+ void describe ( 'validateResponse()' , ( ) => {
12+ void it ( 'should validate the response' , async ( ) =>
13+ assert . equal (
14+ await middy ( )
15+ . use ( validateResponse ( Type . Boolean ( { title : 'A boolean' } ) ) )
16+ . handler ( async ( ) => true ) ( 'Some event' , { } as Context ) ,
17+ true ,
18+ ) )
19+
20+ void it ( 'should throw an Error in case the response is invalid' , async ( ) =>
21+ assert . rejects (
22+ async ( ) =>
23+ middy ( )
24+ . use ( validateResponse ( Type . Boolean ( ) ) )
25+ . handler ( async ( ) => 42 ) ( 'Some event' , { } as Context ) ,
26+ ResponseValidationFailedError ,
27+ ) )
28+ } )
Original file line number Diff line number Diff line change 1+ import {
2+ formatTypeBoxErrors ,
3+ validateWithTypeBox ,
4+ } from '@hello.nrfcloud.com/proto'
5+ import type middy from '@middy/core'
6+ import type { TSchema } from '@sinclair/typebox'
7+ import type { ValueError } from '@sinclair/typebox/errors'
8+ import { ValidationFailedError } from './validateInput.js'
9+
10+ export class ResponseValidationFailedError extends ValidationFailedError {
11+ constructor ( errors : ValueError [ ] ) {
12+ super ( errors , 'Response validation failed' )
13+ this . name = 'ResponseValidationFailedError'
14+ }
15+ }
16+
17+ export const validateResponse = < ResponseSchema extends TSchema > (
18+ schema : ResponseSchema ,
19+ ) : middy . MiddlewareObj => {
20+ const validator = validateWithTypeBox ( schema )
21+ return {
22+ after : async ( req ) => {
23+ const maybeValid = validator ( req . response )
24+ if ( 'errors' in maybeValid ) {
25+ console . error (
26+ `[validateResponse]` ,
27+ `Response validation failed` ,
28+ JSON . stringify ( {
29+ response : req . response ,
30+ errors : formatTypeBoxErrors ( maybeValid . errors ) ,
31+ } ) ,
32+ )
33+ throw new ResponseValidationFailedError ( maybeValid . errors )
34+ }
35+ console . debug ( `[validateResponse]` , `Response is` , schema . title )
36+ return undefined
37+ } ,
38+ }
39+ }
You can’t perform that action at this time.
0 commit comments