Skip to content

Commit

Permalink
Fix error response properties in errorMiddleware and auth_test_support
Browse files Browse the repository at this point in the history
  • Loading branch information
MXPOL committed Jan 17, 2024
1 parent 736a9a6 commit 694351a
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 32 deletions.
6 changes: 3 additions & 3 deletions apps/velo-external-db/test/e2e/app_data.e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ describe(`Velo External DB Data REST API: ${currentDbImplementationName()}`, ()
})

describe('error handling', () => {
testIfSupportedOperationsIncludes(supportedOperations, [PrimaryKey])('insert api with duplicate _id should fail with WDE0074, 409', async() => {
testIfSupportedOperationsIncludes(supportedOperations, [PrimaryKey])('insert api with duplicate _id should fail with ITEM_NOT_FOUND, 409', async() => {
await schema.givenCollection(ctx.collectionName, [ctx.column], authOwner)
await data.givenItems([ctx.item], ctx.collectionName, authAdmin)

Expand Down Expand Up @@ -363,7 +363,7 @@ describe(`Velo External DB Data REST API: ${currentDbImplementationName()}`, ()
expect(error).toBeDefined()
expect(error.response.status).toEqual(404)
expect(error.response.data).toEqual(expect.objectContaining({
code: 'WDE0025',
errorCode: 'COLLECTION_NOT_FOUND',
data: {
collectionId: 'nonExistingCollection'
}
Expand All @@ -379,7 +379,7 @@ describe(`Velo External DB Data REST API: ${currentDbImplementationName()}`, ()
expect(error).toBeDefined()
expect(error.response.status).toEqual(400)
expect(error.response.data).toEqual(expect.objectContaining({
code: 'WDE0147',
errorCode: 'FIELD_DOESNT_EXIST',
data: {
collectionId: ctx.collectionName,
propertyName: 'nonExistingColumn'
Expand Down
6 changes: 3 additions & 3 deletions apps/velo-external-db/test/e2e/app_data_hooks.e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,7 @@ describe(`Velo External DB Data Hooks: ${currentDbImplementationName()}`, () =>
})

await expect(axios.post('/items/remove', hooks.writeRequestBodyWith(ctx.collectionName, [ctx.item]), authOwner)).rejects.toMatchObject(
errorResponseWith('WDE0054', 'message', 409)
errorResponseWith('UNKNOWN_ERROR', 'message', 409)
)
})

Expand All @@ -540,7 +540,7 @@ describe(`Velo External DB Data Hooks: ${currentDbImplementationName()}`, () =>
})

await expect(axios.post('/items/remove', hooks.writeRequestBodyWith(ctx.collectionName, [ctx.item]), authOwner)).rejects.toMatchObject(
errorResponseWith('WDE0054', 'message', 500)
errorResponseWith('UNKNOWN_ERROR', 'message', 500)
)
})

Expand All @@ -554,7 +554,7 @@ describe(`Velo External DB Data Hooks: ${currentDbImplementationName()}`, () =>
})

await expect(axios.post('/items/remove', hooks.writeRequestBodyWith(ctx.collectionName, [ctx.item]), authOwner)).rejects.toMatchObject(
errorResponseWith('WDE0054', 'message', 500)
errorResponseWith('UNKNOWN_ERROR', 'message', 500)
)
})
})
Expand Down
6 changes: 3 additions & 3 deletions apps/velo-external-db/test/e2e/app_schema_hooks.e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ describe(`Velo External DB Schema Hooks: ${currentDbImplementationName()}`, () =
})

await expect(axiosClient.post('/collections/delete', hooks.collectionWriteRequestBodyWith({ id: ctx.collectionId, fields: [] }), authOwner)).rejects.toMatchObject(
errorResponseWith('WDE0054', 'message', 409)
errorResponseWith('UNKNOWN_ERROR', 'message', 409)
)
})

Expand All @@ -273,7 +273,7 @@ describe(`Velo External DB Schema Hooks: ${currentDbImplementationName()}`, () =
})

await expect(axiosClient.post('/collections/delete', hooks.collectionWriteRequestBodyWith({ id: ctx.collectionId, fields: [] }), authOwner)).rejects.toMatchObject(
errorResponseWith('WDE0054', 'message', 500)
errorResponseWith('UNKNOWN_ERROR', 'message', 500)
)
})

Expand All @@ -287,7 +287,7 @@ describe(`Velo External DB Schema Hooks: ${currentDbImplementationName()}`, () =
})

await expect(axiosClient.post('/collections/delete', hooks.collectionWriteRequestBodyWith({ id: ctx.collectionId, fields: [] }), authOwner)).rejects.toMatchObject(
errorResponseWith('WDE0054', 'message', 500)
errorResponseWith('UNKNOWN_ERROR', 'message', 500)
)
})
})
Expand Down
4 changes: 2 additions & 2 deletions libs/external-db-testkit/src/lib/auth_test_support.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export const authOwnerWithWrongAppId= { transformRequest: axios.defaults



export const errorResponseWith = (code: any, message: string, httpStatusCode: number) => ({ response: { data: { data: { description: expect.stringContaining(message) }, code }, status: httpStatusCode } })
export const errorResponseWith = (errorCode: any, message: string, httpStatusCode: number) => ({ response: { data: { data: { description: expect.stringContaining(message) }, errorCode }, status: httpStatusCode } })

export const collectionChangeNotSupportedErrorResponseWith = (fieldsName: string[]) => ({ response: { data: { data: { errors: fieldsName.map(f => ({ fieldKey: f, message: expect.any(String) })) }, code: 'WDE0119' } } })
export const collectionChangeNotSupportedErrorResponseWith = (fieldsName: string[]) => ({ response: { data: { data: { errors: fieldsName.map(f => ({ fieldKey: f, message: expect.any(String) })) }, errorCode: 'COLLECTION_CHANGE_NOT_SUPPORTED' } } })

52 changes: 34 additions & 18 deletions libs/velo-external-db-core/src/spi-model/errors.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
class BaseWixError extends Error {
collctionName: string
httpCode: HttpStatusCode
applicationCode: ApiErrors
errorCode: ErrorCodes

constructor(message: string, httpCode: HttpStatusCode, applicationCode: ApiErrors, collectionName: string) {
constructor(message: string, httpCode: HttpStatusCode, errorCode: ErrorCodes, collectionName: string) {
super(message)
this.httpCode = httpCode
this.applicationCode = applicationCode
this.errorCode = errorCode
this.collctionName = collectionName
}
}
Expand All @@ -15,7 +15,7 @@ export class CollectionNotFoundError extends BaseWixError {
data: { collectionId: string }

constructor(collectionName: string, message: string) {
super(message, HttpStatusCode.NOT_FOUND, ApiErrors.WDE0025, collectionName)
super(message, HttpStatusCode.NOT_FOUND, ErrorCodes.COLLECTION_NOT_FOUND, collectionName)
this.data = { collectionId: collectionName }
}
}
Expand All @@ -24,7 +24,7 @@ export class CollectionAlreadyExistsError extends BaseWixError {
data: { collectionId: string }

constructor(collectionName: string, message: string) {
super(message, HttpStatusCode.ALREADY_EXISTS, ApiErrors.WDE0104, collectionName)
super(message, HttpStatusCode.ALREADY_EXISTS, ErrorCodes.COLLECTION_ALREADY_EXISTS, collectionName)
this.data = { collectionId: collectionName }
}
}
Expand All @@ -33,7 +33,7 @@ export class ItemNotFoundError extends BaseWixError {
data: { itemId: string }

constructor(collectionName: string, itemId: string, message: string) {
super(message, HttpStatusCode.NOT_FOUND, ApiErrors.WDE0073, collectionName)
super(message, HttpStatusCode.NOT_FOUND, ErrorCodes.ITEM_NOT_FOUND, collectionName)
this.data = { itemId }
}
}
Expand All @@ -42,7 +42,7 @@ export class ItemAlreadyExistsError extends BaseWixError {
data: { itemId: string }

constructor(collectionName: string, itemId: string, message: string) {
super(message, HttpStatusCode.ALREADY_EXISTS, ApiErrors.WDE0074, collectionName)
super(message, HttpStatusCode.ALREADY_EXISTS, ErrorCodes.ITEM_ALREADY_EXISTS, collectionName)
this.data = { itemId }
}
}
Expand All @@ -53,7 +53,7 @@ export class ReferenceNotFoundError extends BaseWixError {
data: { referringItemId: string, referencedItemId: string }

constructor(message: string, collectionName: string, referringItemId: string, referencedItemId: string) {
super(message, HttpStatusCode.NOT_FOUND, ApiErrors.WDE0029, collectionName)
super(message, HttpStatusCode.NOT_FOUND, ErrorCodes.REFERENCE_NOT_FOUND, collectionName)
this.referringItemId = referringItemId
this.referencedItemId = referencedItemId
this.data = { referringItemId, referencedItemId }
Expand All @@ -66,7 +66,7 @@ export class ReferenceAlreadyExistsError extends BaseWixError {
data: { referringItemId: string, referencedItemId: string }

constructor(message: string, collectionName: string, referringItemId: string, referencedItemId: string) {
super(message, HttpStatusCode.ALREADY_EXISTS, ApiErrors.WDE0029, collectionName)
super(message, HttpStatusCode.ALREADY_EXISTS, ErrorCodes.REFERENCE_ALREADY_EXISTS, collectionName)
this.referringItemId = referringItemId
this.referencedItemId = referencedItemId
this.data = { referringItemId, referencedItemId }
Expand All @@ -84,7 +84,7 @@ export class ValidationError extends BaseWixError {
data: { violations: ValidationViolation[] }

constructor(message: string, collectionName: string, fieldPath: string, rejectedValue: string) {
super(message, HttpStatusCode.INVALID_ARGUMENT, ApiErrors.WDE0075, collectionName)
super(message, HttpStatusCode.INVALID_ARGUMENT, ErrorCodes.VALIDATION_ERROR, collectionName)
this.violations = [{ fieldPath, rejectedValue, message }]
this.data = { violations: this.violations }
}
Expand All @@ -100,7 +100,7 @@ export class CollectionChangeNotSupportedError extends BaseWixError {
data: { errors: CollectionChangeNotSupportedErrorItem[] }

constructor(collectionName: string, fieldKey: string, message: string) {
super(message, HttpStatusCode.INVALID_ARGUMENT, ApiErrors.WDE0119, collectionName)
super(message, HttpStatusCode.INVALID_ARGUMENT, ErrorCodes.COLLECTION_CHANGE_NOT_SUPPORTED, collectionName)
this.errors = [{ fieldKey, message }]
this.data = { errors: this.errors }
}
Expand All @@ -109,17 +109,16 @@ export class CollectionChangeNotSupportedError extends BaseWixError {
export class UnknownError extends BaseWixError {
data: { description: string }
constructor(message: string, httpCode: number = HttpStatusCode.INTERNAL) {
super(message, httpCode, ApiErrors.WDE0054, '')
super(message, httpCode, ErrorCodes.UNKNOWN_ERROR, '')
this.data = { description: message }
}
}


export class InvalidPropertyError extends BaseWixError {
export class FieldDoesNotExist extends BaseWixError {
data: { collectionId: string, propertyName: string }

constructor(collectionName: string, propertyName: string, message: string) {
super(message, HttpStatusCode.INVALID_ARGUMENT, ApiErrors.WDE0147, collectionName)
super(message, HttpStatusCode.INVALID_ARGUMENT, ErrorCodes.FIELD_DOESNT_EXIST, collectionName)
this.data = { collectionId: collectionName, propertyName }
}
}
Expand All @@ -128,7 +127,7 @@ export class InvalidPropertyError extends BaseWixError {
export class UnauthorizedError extends BaseWixError {
data: { description: string }
constructor(message: string) {
super(message, HttpStatusCode.UNAUTHENTICATED, ApiErrors.WDE0027, '')
super(message, HttpStatusCode.UNAUTHENTICATED, ErrorCodes.UNAUTHORIZED, '')
this.data = { description: message }
}
}
Expand All @@ -137,7 +136,7 @@ export class FieldAlreadyExistsError extends BaseWixError {
data: { collectionId: string, fieldName: string }

constructor(collectionName: string, fieldName: string, message: string) {
super(message, HttpStatusCode.ALREADY_EXISTS, ApiErrors.WDE0123, collectionName)
super(message, HttpStatusCode.ALREADY_EXISTS, ErrorCodes.FIELD_ALREADY_EXISTS, collectionName)
this.data = { collectionId: collectionName, fieldName }
}
}
Expand All @@ -146,7 +145,7 @@ export class UnsupportedSchemaOperation extends BaseWixError {
data: { collectionId: string, operation: string }

constructor(collectionName: string, operation: string, message: string) {
super(message, HttpStatusCode.INVALID_ARGUMENT, ApiErrors.WDE0119, collectionName)
super(message, HttpStatusCode.INVALID_ARGUMENT, ErrorCodes.UNSUPPORTED_OPERATION, collectionName)
this.data = { collectionId: collectionName, operation }
}
}
Expand Down Expand Up @@ -263,3 +262,20 @@ export enum HttpStatusCode {
// DATA_LOSS = 14; // 500
// UNIMPLEMENTED = 15; // 501
}

enum ErrorCodes {
ITEM_ALREADY_EXISTS = 'ITEM_ALREADY_EXISTS',
ITEM_NOT_FOUND = 'ITEM_NOT_FOUND',
COLLECTION_ALREADY_EXISTS = 'COLLECTION_ALREADY_EXISTS',
COLLECTION_NOT_FOUND = 'COLLECTION_NOT_FOUND',
REFERENCE_ALREADY_EXISTS = 'REFERENCE_ALREADY_EXISTS',
REFERENCE_NOT_FOUND = 'REFERENCE_NOT_FOUND',
VALIDATION_ERROR = 'VALIDATION_ERROR',
COLLECTION_CHANGE_NOT_SUPPORTED = 'COLLECTION_CHANGE_NOT_SUPPORTED',
// These errors are not in the official SPI
FIELD_DOESNT_EXIST = 'FIELD_DOESNT_EXIST',
FIELD_ALREADY_EXISTS = 'FIELD_ALREADY_EXISTS',
UNAUTHORIZED = 'UNAUTHORIZED',
UNSUPPORTED_OPERATION = 'UNSUPPORTED_OPERATION',
UNKNOWN_ERROR = 'UNKNOWN_ERROR'
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { errors as domainErrors } from '@wix-velo/velo-external-db-commons'
import { ItemAlreadyExistsError, CollectionNotFoundError, ItemNotFoundError, CollectionAlreadyExistsError, CollectionChangeNotSupportedError,
UnknownError, InvalidPropertyError, UnauthorizedError, FieldAlreadyExistsError, UnsupportedSchemaOperation } from '../spi-model/errors'
UnknownError, FieldDoesNotExist, UnauthorizedError, FieldAlreadyExistsError, UnsupportedSchemaOperation } from '../spi-model/errors'

export const domainToSpiErrorTranslator = (err: any) => {
switch(err.constructor) {
Expand All @@ -18,7 +18,7 @@ export const domainToSpiErrorTranslator = (err: any) => {

case domainErrors.FieldDoesNotExist:
const fieldDoesNotExist = err as domainErrors.FieldDoesNotExist
return new InvalidPropertyError(fieldDoesNotExist.collectionName, fieldDoesNotExist.propertyName, fieldDoesNotExist.message)
return new FieldDoesNotExist(fieldDoesNotExist.collectionName, fieldDoesNotExist.propertyName, fieldDoesNotExist.message)

case domainErrors.UnsupportedSchemaOperation:
const unsupportedSchemaOperation = err as domainErrors.UnsupportedSchemaOperation
Expand Down
2 changes: 1 addition & 1 deletion libs/velo-external-db-core/src/web/error-middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ export const errorMiddleware = (err: any, _req: any, res: Response, _next?: Next
const error = domainToSpiErrorTranslator(err)
res.status(error.httpCode).send({
data: error.data,
code: error.applicationCode
errorCode: error.errorCode,
})
}

0 comments on commit 694351a

Please sign in to comment.