Skip to content

Commit

Permalink
Added synchronous responses for rules engine invalid quote errors (#127)
Browse files Browse the repository at this point in the history
* Added synchronous responses for rules engine invalid quote errors

* Corrected import

* Corrected error variable name

* Moved response handling out of model, into handlers

* Fixed tests
  • Loading branch information
partiallyordered authored Jan 16, 2020
1 parent 745d45f commit f6e8f6c
Show file tree
Hide file tree
Showing 10 changed files with 107 additions and 36 deletions.
80 changes: 66 additions & 14 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
"@mojaloop/central-services-shared": "8.7.1",
"@mojaloop/event-sdk": "8.6.2",
"@mojaloop/ml-number": "8.2.0",
"@mojaloop/sdk-standard-components": "^8.6.9",
"axios": "0.19.0",
"blipp": "4.0.1",
"eslint-config-standard": "14.1.0",
Expand Down
7 changes: 3 additions & 4 deletions src/handlers/quotes.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,13 @@ module.exports = {
// call the quote request handler in the model
const result = await model.handleQuoteRequest(request.headers, request.payload, span)
request.server.log(['info'], `POST quote request succeeded and returned: ${util.inspect(result)}`)
return h.response().code(Enum.Http.ReturnCodes.ACCEPTED.CODE)
} catch (err) {
// something went wrong, use the model to handle the error in a sensible way
request.server.log(['error'], `ERROR - POST /quotes: ${LibUtil.getStackOrInspect(err)}`)
const fspiopError = ErrorHandler.ReformatFSPIOPError(err)
await model.handleException(fspiopSource, quoteId, fspiopError, request.headers, span)
} finally {
// eslint-disable-next-line no-unsafe-finally
return h.response().code(Enum.Http.ReturnCodes.ACCEPTED.CODE)
const { body, code } = await model.handleException(fspiopSource, quoteId, fspiopError, request.headers, span)
return h.response(body).code(code)
}
}
}
14 changes: 6 additions & 8 deletions src/handlers/quotes/{id}.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,12 @@ module.exports = {
// will send the callback to the correct party regardless.
const result = await model.handleQuoteGet(request.headers, quoteId, span)
request.server.log(['info'], `GET quotes/{id} request succeeded and returned: ${util.inspect(result)}`)
return h.response().code(202)
} catch (err) {
// something went wrong, use the model to handle the error in a sensible way
request.server.log(['error'], `ERROR - GET /quotes/{id}: ${LibUtil.getStackOrInspect(err)}`)
await model.handleException(fspiopSource, quoteId, err, request.headers, span)
} finally {
// eslint-disable-next-line no-unsafe-finally
return h.response().code(202)
const { body, code } = await model.handleException(fspiopSource, quoteId, err, request.headers, span)
return h.response(body).code(code)
}
},

Expand Down Expand Up @@ -121,13 +120,12 @@ module.exports = {
// call the quote update handler in the model
const result = await model.handleQuoteUpdate(request.headers, quoteId, request.payload, span)
request.server.log(['info'], `PUT quote request succeeded and returned: ${util.inspect(result)}`)
return h.response().code(202)
} catch (err) {
// something went wrong, use the model to handle the error in a sensible way
request.server.log(['error'], `ERROR - PUT /quotes/{id}: ${LibUtil.getStackOrInspect(err)}`)
await model.handleException(fspiopSource, quoteId, err, request.headers, span)
} finally {
// eslint-disable-next-line no-unsafe-finally
return h.response().code(202)
const { body, code } = await model.handleException(fspiopSource, quoteId, err, request.headers, span)
return h.response(body).code(code)
}
}
}
7 changes: 3 additions & 4 deletions src/handlers/quotes/{id}/error.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,12 @@ module.exports = {
// call the quote error handler in the model
const result = await model.handleQuoteError(request.headers, quoteId, request.payload.errorInformation, span)
request.server.log(['info'], `PUT quote error request succeeded and returned: ${util.inspect(result)}`)
return h.response().code(Enum.Http.ReturnCodes.OK.CODE)
} catch (err) {
// something went wrong, use the model to handle the error in a sensible way
request.server.log(['error'], `ERROR - PUT /quotes/{id}/error: ${LibUtil.getStackOrInspect(err)}`)
await model.handleException(fspiopSource, quoteId, err, request.headers)
} finally {
// eslint-disable-next-line no-unsafe-finally
return h.response().code(Enum.Http.ReturnCodes.OK.CODE)
const { body, code } = await model.handleException(fspiopSource, quoteId, err, request.headers, span)
return h.response(body).code(code)
}
}
}
24 changes: 23 additions & 1 deletion src/model/quotes.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ const axios = require('axios')
const crypto = require('crypto')
const util = require('util')

const { MojaloopApiErrorCodes } = require('@mojaloop/sdk-standard-components').Errors
const ENUM = require('@mojaloop/central-services-shared').Enum
const ErrorHandler = require('@mojaloop/central-services-error-handling')
const EventSdk = require('@mojaloop/event-sdk')
Expand Down Expand Up @@ -826,7 +827,28 @@ class QuotesModel {
const childSpan = span.getChild('qs_quote_sendErrorCallback')
try {
await childSpan.audit({ headers, params: { quoteId } }, EventSdk.AuditEventAction.start)
return await this.sendErrorCallback(fspiopSource, fspiopError, quoteId, headers, childSpan)
const syncErrorCodes = [
MojaloopApiErrorCodes.MISSING_ELEMENT.code,
MojaloopApiErrorCodes.PAYEE_ERROR.code,
MojaloopApiErrorCodes.PAYEE_UNSUPPORTED_CURRENCY.code,
MojaloopApiErrorCodes.PAYER_ERROR.code,
MojaloopApiErrorCodes.PAYER_UNSUPPORTED_CURRENCY.code
];
if (error.name === 'FSPIOPError' && syncErrorCodes.includes(error.apiErrorCode.code)) {
// We should respond synchronously
const envConfig = new Config()
return {
body: error.toApiErrorObject(envConfig.errorHandling),
code: ENUM.Http.ReturnCodes.BADREQUEST
}
}
else {
// We should respond asynchronously
await this.sendErrorCallback(fspiopSource, fspiopError, quoteId, headers, childSpan)
return {
code: ENUM.Http.ReturnCodes.ACCEPTED.CODE
}
}
} catch (err) {
// any-error
// not much we can do other than log the error
Expand Down
2 changes: 1 addition & 1 deletion test/unit/handlers/quotes.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ describe('/quotes', () => {

it('fails to create a quote', async () => {
// Arrange
const handleException = jest.fn()
const handleException = jest.fn(() => ({ code: Enum.Http.ReturnCodes.ACCEPTED.CODE }))
QuotesModel.mockImplementationOnce(() => ({
handleQuoteRequest: () => {
throw new Error('Create Quote Test Error')
Expand Down
4 changes: 2 additions & 2 deletions test/unit/handlers/quotes/{id}.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ describe('/quotes/{id}', () => {

it('handles an error with the model', async () => {
// Arrange
const handleException = jest.fn()
const handleException = jest.fn(() => ({ code: 202 }))
QuotesModel.mockImplementationOnce(() => {
return {
handleQuoteGet: () => {
Expand Down Expand Up @@ -113,7 +113,7 @@ describe('/quotes/{id}', () => {

it('handles an error with the model', async () => {
// Arrange
const handleException = jest.fn()
const handleException = jest.fn(() => ({ code: 202 }))
QuotesModel.mockImplementationOnce(() => {
return {
handleQuoteUpdate: () => {
Expand Down
2 changes: 1 addition & 1 deletion test/unit/handlers/quotes/{id}/error.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ describe('/quotes/{id}', () => {
}
}
}
const handleException = jest.fn()
const handleException = jest.fn(() => ({ code: Enum.Http.ReturnCodes.OK.CODE }))
QuotesModel.mockImplementationOnce(() => {
return {
handleQuoteError: () => {
Expand Down
2 changes: 1 addition & 1 deletion test/unit/model/quotes.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1815,7 +1815,7 @@ describe('QuotesModel', () => {

// Assert
expect(quotesModel.sendErrorCallback).toHaveBeenCalledWith('payeefsp', expectedError, mockData.quoteId, mockData.headers, mockChildSpan)
expect(result).toBe(true)
expect(result).toStrictEqual({ code: 202 })
expect(mockChildSpan.finish).toHaveBeenCalledTimes(1)
})

Expand Down

0 comments on commit f6e8f6c

Please sign in to comment.