From 9af9f0b4b828d1cfed598cd394543313e5f8392e Mon Sep 17 00:00:00 2001 From: moritzraho Date: Wed, 12 Feb 2025 16:40:35 +0100 Subject: [PATCH] fix!: error codes --- lib/AdobeState.js | 31 ++++++++++++++++++------------- lib/StateError.js | 9 ++++----- test/AdobeState.test.js | 32 +++++++++++++++++++++++--------- 3 files changed, 45 insertions(+), 27 deletions(-) diff --git a/lib/AdobeState.js b/lib/AdobeState.js index 01d36ce..3504d71 100644 --- a/lib/AdobeState.js +++ b/lib/AdobeState.js @@ -112,20 +112,25 @@ async function handleResponse (response, params) { const copyParams = cloneDeep(params) copyParams.requestId = response.headers.get(REQUEST_ID_HEADER) - switch (response.status) { - case 404: - return response - case 401: - return logAndThrow(new codes.ERROR_UNAUTHORIZED({ messageValues: ['State service'], sdkDetails: copyParams })) - case 403: - return logAndThrow(new codes.ERROR_BAD_CREDENTIALS({ messageValues: ['State service'], sdkDetails: copyParams })) - case 413: - return logAndThrow(new codes.ERROR_PAYLOAD_TOO_LARGE({ messageValues: ['State service'], sdkDetails: copyParams })) - case 429: - return logAndThrow(new codes.ERROR_REQUEST_RATE_TOO_HIGH({ sdkDetails: copyParams })) - default: // 500 errors - return logAndThrow(new codes.ERROR_INTERNAL({ messageValues: [`unexpected response from State service with status: ${response.status} body: ${await response.text()}`], sdkDetails: copyParams })) + const body = await response.text() + if (response.status < 500) { + switch (response.status) { + case 404: + return response // 404s are not an error + case 401: + return logAndThrow(new codes.ERROR_UNAUTHORIZED({ messageValues: [body], sdkDetails: copyParams })) + case 403: + return logAndThrow(new codes.ERROR_FORBIDDEN({ messageValues: [body], sdkDetails: copyParams })) + case 413: + return logAndThrow(new codes.ERROR_PAYLOAD_TOO_LARGE({ messageValues: [body], sdkDetails: copyParams })) + case 429: + return logAndThrow(new codes.ERROR_REQUEST_RATE_TOO_HIGH({ messageValues: [body], sdkDetails: copyParams })) + default: // other 4xx errors + return logAndThrow(new codes.ERROR_BAD_REQUEST({ messageValues: [body], sdkDetails: copyParams })) + } } + // 500 errors + return logAndThrow(new codes.ERROR_INTERNAL({ messageValues: [`unexpected response from State service with body: ${body}`], sdkDetails: copyParams })) } /** @private */ diff --git a/lib/StateError.js b/lib/StateError.js index 02f2d98..4b089fb 100644 --- a/lib/StateError.js +++ b/lib/StateError.js @@ -56,11 +56,10 @@ E('ERROR_INTERNAL', '%s') E('ERROR_BAD_REQUEST', '%s') E('ERROR_BAD_ARGUMENT', '%s') E('ERROR_UNEXPECTED_NOT_FOUND', '%s') -E('ERROR_UNKNOWN_PROVIDER', '%s') -E('ERROR_UNAUTHORIZED', 'you are not authorized to access %s') -E('ERROR_BAD_CREDENTIALS', 'cannot access %s, make sure your credentials are valid') -E('ERROR_PAYLOAD_TOO_LARGE', 'key, value or request payload is too large') -E('ERROR_REQUEST_RATE_TOO_HIGH', 'Request rate too high. Please retry after sometime.') +E('ERROR_UNAUTHORIZED', '%s') +E('ERROR_FORBIDDEN', '%s') +E('ERROR_PAYLOAD_TOO_LARGE', '%s') +E('ERROR_REQUEST_RATE_TOO_HIGH', '%s') // eslint-disable-next-line jsdoc/require-jsdoc function logAndThrow (e) { diff --git a/test/AdobeState.test.js b/test/AdobeState.test.js index 9f73356..8879f7b 100644 --- a/test/AdobeState.test.js +++ b/test/AdobeState.test.js @@ -271,13 +271,13 @@ describe('put', () => { const key = 'some-key' const value = 'some-value' - mockExponentialBackoff.mockResolvedValue(wrapInFetchError(401)) + mockExponentialBackoff.mockResolvedValue(wrapInFetchError(401, 'myerror')) await expect(store.put(key, value)).rejects.toThrow( expect.objectContaining({ sdkDetails: expect.objectContaining({ requestId: 'fake-req-id' }), - message: '[AdobeStateLib:ERROR_UNAUTHORIZED] you are not authorized to access State service' + message: '[AdobeStateLib:ERROR_UNAUTHORIZED] myerror' })) }) @@ -285,13 +285,13 @@ describe('put', () => { const key = 'some-key' const value = 'some-value' - mockExponentialBackoff.mockResolvedValue(wrapInFetchError(403)) + mockExponentialBackoff.mockResolvedValue(wrapInFetchError(403, 'myerror')) await expect(store.put(key, value)).rejects.toThrow( expect.objectContaining({ sdkDetails: expect.objectContaining({ requestId: 'fake-req-id' }), - message: '[AdobeStateLib:ERROR_BAD_CREDENTIALS] cannot access State service, make sure your credentials are valid' + message: '[AdobeStateLib:ERROR_FORBIDDEN] myerror' })) }) @@ -299,13 +299,13 @@ describe('put', () => { const key = 'some-key' const value = 'some-value' - mockExponentialBackoff.mockResolvedValue(wrapInFetchError(413)) + mockExponentialBackoff.mockResolvedValue(wrapInFetchError(413, 'myerror')) await expect(store.put(key, value)).rejects.toThrow( expect.objectContaining({ sdkDetails: expect.objectContaining({ requestId: 'fake-req-id' }), - message: '[AdobeStateLib:ERROR_PAYLOAD_TOO_LARGE] key, value or request payload is too large State service' + message: '[AdobeStateLib:ERROR_PAYLOAD_TOO_LARGE] myerror' })) }) @@ -313,13 +313,27 @@ describe('put', () => { const key = 'some-key' const value = 'some-value' - mockExponentialBackoff.mockResolvedValue(wrapInFetchError(429)) + mockExponentialBackoff.mockResolvedValue(wrapInFetchError(429, 'myerror')) await expect(store.put(key, value)).rejects.toThrow( expect.objectContaining({ sdkDetails: expect.objectContaining({ requestId: 'fake-req-id' }), - message: '[AdobeStateLib:ERROR_REQUEST_RATE_TOO_HIGH] Request rate too high. Please retry after sometime.' + message: '[AdobeStateLib:ERROR_REQUEST_RATE_TOO_HIGH] myerror' + })) + }) + test('coverage: unknown user error', async () => { + const key = 'some-key' + const value = 'some-value' + const responseBody = 'error: this is the response body' + + mockExponentialBackoff.mockResolvedValue(wrapInFetchError(400, responseBody)) + await expect(store.put(key, value)).rejects.toThrow( + expect.objectContaining({ + sdkDetails: expect.objectContaining({ + requestId: 'fake-req-id' + }), + message: `[AdobeStateLib:ERROR_BAD_REQUEST] ${responseBody}` })) }) @@ -334,7 +348,7 @@ describe('put', () => { sdkDetails: expect.objectContaining({ requestId: 'fake-req-id' }), - message: `[AdobeStateLib:ERROR_INTERNAL] unexpected response from State service with status: 500 body: ${responseBody}` + message: `[AdobeStateLib:ERROR_INTERNAL] unexpected response from State service with body: ${responseBody}` })) })