mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	Chore: remove "dataPath" from data OpenAPI data errors. (#5272)
The `dataPath` was present (but not in the type) in previous versions of the error library that we use. But with the recent major upgrade, it's been removed and the `instancePath` property has finally come into use. This PR removes all the handling for the previous property and replaces it with `instancePath`. Because the `dataPath` used full stops and the `instancePath` uses slashes, we need to change a little bit of the handling too.
This commit is contained in:
		
							parent
							
								
									92e2b1890c
								
							
						
					
					
						commit
						b3054c9277
					
				| @ -38,7 +38,7 @@ class BadDataError extends UnleashError { | |||||||
| export default BadDataError; | export default BadDataError; | ||||||
| 
 | 
 | ||||||
| const constructPath = (pathToParent: string, propertyName: string) => | const constructPath = (pathToParent: string, propertyName: string) => | ||||||
|     [pathToParent, propertyName].filter(Boolean).join('.'); |     [pathToParent, propertyName].filter(Boolean).join('/'); | ||||||
| 
 | 
 | ||||||
| const missingRequiredPropertyMessage = ( | const missingRequiredPropertyMessage = ( | ||||||
|     pathToParentObject: string, |     pathToParentObject: string, | ||||||
| @ -74,10 +74,10 @@ const genericErrorMessage = ( | |||||||
|     propertyName: string, |     propertyName: string, | ||||||
|     errorMessage: string = 'is invalid', |     errorMessage: string = 'is invalid', | ||||||
| ) => { | ) => { | ||||||
|     const input = getProp(requestBody, propertyName); |     const input = getProp(requestBody, propertyName.split('/')); | ||||||
| 
 | 
 | ||||||
|     const youSent = JSON.stringify(input); |     const youSent = JSON.stringify(input); | ||||||
|     const description = `The \`.${propertyName}\` property ${errorMessage}. You sent ${youSent}.`; |     const description = `The \`${propertyName}\` property ${errorMessage}. You sent ${youSent}.`; | ||||||
|     return { |     return { | ||||||
|         description, |         description, | ||||||
|         message: description, |         message: description, | ||||||
| @ -122,16 +122,11 @@ const enumMessage = ( | |||||||
|     }; |     }; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| // Sometimes, the error object contains a dataPath, even if it's not
 |  | ||||||
| type ActualErrorObject = ErrorObject & { dataPath?: string }; |  | ||||||
| 
 |  | ||||||
| export const fromOpenApiValidationError = | export const fromOpenApiValidationError = | ||||||
|     (requestBody: object) => |     (requestBody: object) => | ||||||
|     (validationError: ActualErrorObject): ValidationErrorDescription => { |     (validationError: ErrorObject): ValidationErrorDescription => { | ||||||
|         const { instancePath, params, message, dataPath } = validationError; |         const { instancePath, params, message } = validationError; | ||||||
|         const propertyName = |         const propertyName = instancePath.substring('/body/'.length); | ||||||
|             dataPath?.substring('.body.'.length) ?? |  | ||||||
|             instancePath.substring('/body/'.length); |  | ||||||
| 
 | 
 | ||||||
|         switch (validationError.keyword) { |         switch (validationError.keyword) { | ||||||
|             case 'required': |             case 'required': | ||||||
|  | |||||||
| @ -50,8 +50,7 @@ describe('OpenAPI error conversion', () => { | |||||||
|     it('Gives useful error messages for missing properties', () => { |     it('Gives useful error messages for missing properties', () => { | ||||||
|         const error = { |         const error = { | ||||||
|             keyword: 'required', |             keyword: 'required', | ||||||
|             instancePath: '', |             instancePath: '/body', | ||||||
|             dataPath: '.body', |  | ||||||
|             schemaPath: '#/components/schemas/addonCreateUpdateSchema/required', |             schemaPath: '#/components/schemas/addonCreateUpdateSchema/required', | ||||||
|             params: { |             params: { | ||||||
|                 missingProperty: 'enabled', |                 missingProperty: 'enabled', | ||||||
| @ -75,8 +74,7 @@ describe('OpenAPI error conversion', () => { | |||||||
|     it('Gives useful error messages for type errors', () => { |     it('Gives useful error messages for type errors', () => { | ||||||
|         const error = { |         const error = { | ||||||
|             keyword: 'type', |             keyword: 'type', | ||||||
|             instancePath: '', |             instancePath: '/body/parameters', | ||||||
|             dataPath: '.body.parameters', |  | ||||||
|             schemaPath: |             schemaPath: | ||||||
|                 '#/components/schemas/addonCreateUpdateSchema/properties/parameters/type', |                 '#/components/schemas/addonCreateUpdateSchema/properties/parameters/type', | ||||||
|             params: { |             params: { | ||||||
| @ -101,13 +99,12 @@ describe('OpenAPI error conversion', () => { | |||||||
|         expect(result.description).toContain(JSON.stringify(parameterValue)); |         expect(result.description).toContain(JSON.stringify(parameterValue)); | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     it.each(['.body', '.body.subObject'])( |     it.each(['/body', '/body/subObject'])( | ||||||
|         'Gives useful error messages for oneOf errors in %s', |         'Gives useful error messages for oneOf errors in %s', | ||||||
|         (dataPath) => { |         (instancePath) => { | ||||||
|             const error = { |             const error = { | ||||||
|                 keyword: 'oneOf', |                 keyword: 'oneOf', | ||||||
|                 instancePath: '', |                 instancePath, | ||||||
|                 dataPath, |  | ||||||
|                 schemaPath: '#/components/schemas/createApiTokenSchema/oneOf', |                 schemaPath: '#/components/schemas/createApiTokenSchema/oneOf', | ||||||
|                 params: { |                 params: { | ||||||
|                     passingSchemas: null, |                     passingSchemas: null, | ||||||
| @ -125,7 +122,7 @@ describe('OpenAPI error conversion', () => { | |||||||
|                 description: |                 description: | ||||||
|                     // it provides the message
 |                     // it provides the message
 | ||||||
|                     expect.stringContaining(error.message), |                     expect.stringContaining(error.message), | ||||||
|                 path: dataPath.substring('.body.'.length), |                 path: instancePath.substring('/body/'.length), | ||||||
|             }); |             }); | ||||||
| 
 | 
 | ||||||
|             // it tells the user what happened
 |             // it tells the user what happened
 | ||||||
| @ -134,18 +131,17 @@ describe('OpenAPI error conversion', () => { | |||||||
|             ); |             ); | ||||||
|             // it tells the user what part of the request body this pertains to
 |             // it tells the user what part of the request body this pertains to
 | ||||||
|             expect(result.description).toContain( |             expect(result.description).toContain( | ||||||
|                 dataPath === '.body' |                 instancePath === '/body' | ||||||
|                     ? 'root object' |                     ? 'root object' | ||||||
|                     : `"${dataPath.substring('.body.'.length)}" property`, |                     : `"${instancePath.substring('/body/'.length)}" property`, | ||||||
|             ); |             ); | ||||||
|         }, |         }, | ||||||
|     ); |     ); | ||||||
| 
 | 
 | ||||||
|     it('Gives useful pattern error messages', () => { |     it('Gives useful pattern error messages', () => { | ||||||
|         const error = { |         const error = { | ||||||
|             instancePath: '', |  | ||||||
|             keyword: 'pattern', |             keyword: 'pattern', | ||||||
|             dataPath: '.body.description', |             instancePath: '/body/description', | ||||||
|             schemaPath: |             schemaPath: | ||||||
|                 '#/components/schemas/addonCreateUpdateSchema/properties/description/pattern', |                 '#/components/schemas/addonCreateUpdateSchema/properties/description/pattern', | ||||||
|             params: { |             params: { | ||||||
| @ -199,9 +195,8 @@ describe('OpenAPI error conversion', () => { | |||||||
| 
 | 
 | ||||||
|     it('Gives useful min/maxlength error messages', () => { |     it('Gives useful min/maxlength error messages', () => { | ||||||
|         const error = { |         const error = { | ||||||
|             instancePath: '', |  | ||||||
|             keyword: 'maxLength', |             keyword: 'maxLength', | ||||||
|             dataPath: '.body.description', |             instancePath: '/body/description', | ||||||
|             schemaPath: |             schemaPath: | ||||||
|                 '#/components/schemas/addonCreateUpdateSchema/properties/description/maxLength', |                 '#/components/schemas/addonCreateUpdateSchema/properties/description/maxLength', | ||||||
|             params: { |             params: { | ||||||
| @ -230,8 +225,7 @@ describe('OpenAPI error conversion', () => { | |||||||
|     it('Handles numerical min/max errors', () => { |     it('Handles numerical min/max errors', () => { | ||||||
|         const error = { |         const error = { | ||||||
|             keyword: 'maximum', |             keyword: 'maximum', | ||||||
|             instancePath: '', |             instancePath: '/body/newprop', | ||||||
|             dataPath: '.body.newprop', |  | ||||||
|             schemaPath: |             schemaPath: | ||||||
|                 '#/components/schemas/addonCreateUpdateSchema/properties/newprop/maximum', |                 '#/components/schemas/addonCreateUpdateSchema/properties/newprop/maximum', | ||||||
|             params: { |             params: { | ||||||
| @ -265,9 +259,7 @@ describe('OpenAPI error conversion', () => { | |||||||
|         const errors: [ErrorObject, ...ErrorObject[]] = [ |         const errors: [ErrorObject, ...ErrorObject[]] = [ | ||||||
|             { |             { | ||||||
|                 keyword: 'maximum', |                 keyword: 'maximum', | ||||||
|                 instancePath: '', |                 instancePath: '/body/newprop', | ||||||
|                 // @ts-expect-error
 |  | ||||||
|                 dataPath: '.body.newprop', |  | ||||||
|                 schemaPath: |                 schemaPath: | ||||||
|                     '#/components/schemas/addonCreateUpdateSchema/properties/newprop/maximum', |                     '#/components/schemas/addonCreateUpdateSchema/properties/newprop/maximum', | ||||||
|                 params: { |                 params: { | ||||||
| @ -279,8 +271,7 @@ describe('OpenAPI error conversion', () => { | |||||||
|             }, |             }, | ||||||
|             { |             { | ||||||
|                 keyword: 'required', |                 keyword: 'required', | ||||||
|                 instancePath: '', |                 instancePath: '/body', | ||||||
|                 dataPath: '.body', |  | ||||||
|                 schemaPath: |                 schemaPath: | ||||||
|                     '#/components/schemas/addonCreateUpdateSchema/required', |                     '#/components/schemas/addonCreateUpdateSchema/required', | ||||||
|                 params: { |                 params: { | ||||||
| @ -312,8 +303,7 @@ describe('OpenAPI error conversion', () => { | |||||||
|         it('gives useful messages for base-level properties', () => { |         it('gives useful messages for base-level properties', () => { | ||||||
|             const openApiError = { |             const openApiError = { | ||||||
|                 keyword: 'additionalProperties', |                 keyword: 'additionalProperties', | ||||||
|                 instancePath: '', |                 instancePath: '/body', | ||||||
|                 dataPath: '.body', |  | ||||||
|                 schemaPath: |                 schemaPath: | ||||||
|                     '#/components/schemas/addonCreateUpdateSchema/additionalProperties', |                     '#/components/schemas/addonCreateUpdateSchema/additionalProperties', | ||||||
|                 params: { additionalProperty: 'bogus' }, |                 params: { additionalProperty: 'bogus' }, | ||||||
| @ -343,8 +333,7 @@ describe('OpenAPI error conversion', () => { | |||||||
|             }; |             }; | ||||||
|             const openApiError = { |             const openApiError = { | ||||||
|                 keyword: 'additionalProperties', |                 keyword: 'additionalProperties', | ||||||
|                 instancePath: '', |                 instancePath: '/body/nestedObject/nested2', | ||||||
|                 dataPath: '.body.nestedObject.nested2', |  | ||||||
|                 schemaPath: |                 schemaPath: | ||||||
|                     '#/components/schemas/addonCreateUpdateSchema/properties/nestedObject/properties/nested2/additionalProperties', |                     '#/components/schemas/addonCreateUpdateSchema/properties/nestedObject/properties/nested2/additionalProperties', | ||||||
|                 params: { additionalProperty: 'extraPropertyName' }, |                 params: { additionalProperty: 'extraPropertyName' }, | ||||||
| @ -354,8 +343,8 @@ describe('OpenAPI error conversion', () => { | |||||||
|             const error = fromOpenApiValidationError(request2)(openApiError); |             const error = fromOpenApiValidationError(request2)(openApiError); | ||||||
| 
 | 
 | ||||||
|             expect(error).toMatchObject({ |             expect(error).toMatchObject({ | ||||||
|                 description: expect.stringContaining('nestedObject.nested2'), |                 description: expect.stringContaining('nestedObject/nested2'), | ||||||
|                 path: 'nestedObject.nested2.extraPropertyName', |                 path: 'nestedObject/nested2/extraPropertyName', | ||||||
|             }); |             }); | ||||||
| 
 | 
 | ||||||
|             expect(error.description).toContain( |             expect(error.description).toContain( | ||||||
| @ -368,12 +357,11 @@ describe('OpenAPI error conversion', () => { | |||||||
|     it('Handles deeply nested properties gracefully', () => { |     it('Handles deeply nested properties gracefully', () => { | ||||||
|         const error = { |         const error = { | ||||||
|             keyword: 'type', |             keyword: 'type', | ||||||
|             dataPath: '.body.nestedObject.a.b', |             instancePath: '/body/nestedObject/a/b', | ||||||
|             schemaPath: |             schemaPath: | ||||||
|                 '#/components/schemas/addonCreateUpdateSchema/properties/nestedObject/properties/a/properties/b/type', |                 '#/components/schemas/addonCreateUpdateSchema/properties/nestedObject/properties/a/properties/b/type', | ||||||
|             params: { type: 'string' }, |             params: { type: 'string' }, | ||||||
|             message: 'should be string', |             message: 'should be string', | ||||||
|             instancePath: '', |  | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|         const result = fromOpenApiValidationError({ |         const result = fromOpenApiValidationError({ | ||||||
| @ -381,8 +369,8 @@ describe('OpenAPI error conversion', () => { | |||||||
|         })(error); |         })(error); | ||||||
| 
 | 
 | ||||||
|         expect(result).toMatchObject({ |         expect(result).toMatchObject({ | ||||||
|             description: expect.stringMatching(/\bnestedObject.a.b\b/), |             description: expect.stringMatching(/\bnestedObject\/a\/b\b/), | ||||||
|             path: 'nestedObject.a.b', |             path: 'nestedObject/a/b', | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         expect(result.description).toContain('[]'); |         expect(result.description).toContain('[]'); | ||||||
| @ -391,11 +379,10 @@ describe('OpenAPI error conversion', () => { | |||||||
|     it('Handles deeply nested properties on referenced schemas', () => { |     it('Handles deeply nested properties on referenced schemas', () => { | ||||||
|         const error = { |         const error = { | ||||||
|             keyword: 'type', |             keyword: 'type', | ||||||
|             dataPath: '.body.nestedObject.a.b', |             instancePath: '/body/nestedObject/a/b', | ||||||
|             schemaPath: '#/components/schemas/parametersSchema/type', |             schemaPath: '#/components/schemas/parametersSchema/type', | ||||||
|             params: { type: 'object' }, |             params: { type: 'object' }, | ||||||
|             message: 'should be object', |             message: 'should be object', | ||||||
|             instancePath: '', |  | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|         const illegalValue = 'illegal string'; |         const illegalValue = 'illegal string'; | ||||||
| @ -405,10 +392,10 @@ describe('OpenAPI error conversion', () => { | |||||||
| 
 | 
 | ||||||
|         expect(result).toMatchObject({ |         expect(result).toMatchObject({ | ||||||
|             description: expect.stringContaining(illegalValue), |             description: expect.stringContaining(illegalValue), | ||||||
|             path: 'nestedObject.a.b', |             path: 'nestedObject/a/b', | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         expect(result.description).toMatch(/\bnestedObject.a.b\b/); |         expect(result.description).toMatch(/\bnestedObject\/a\/b\b/); | ||||||
|     }); |     }); | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user