When serviceData fails validation, include the service class in the stack trace (#4266)

This should make it easier to debug #3784.
This commit is contained in:
Paul Melnikow
2019-10-28 10:33:47 -04:00
committed by GitHub
parent 50a2660aa5
commit 7e0976cd8c
2 changed files with 39 additions and 15 deletions

View File

@@ -267,6 +267,12 @@ class BaseService {
throw new Error(`Handler not implemented for ${this.constructor.name}`) throw new Error(`Handler not implemented for ${this.constructor.name}`)
} }
// Making this an instance method ensures debuggability.
// https://github.com/badges/shields/issues/3784
_validateServiceData(serviceData) {
Joi.assert(serviceData, serviceDataSchema)
}
_handleError(error) { _handleError(error) {
if (error instanceof NotFound || error instanceof InvalidParameter) { if (error instanceof NotFound || error instanceof InvalidParameter) {
trace.logTrace('outbound', emojic.noGoodWoman, 'Handled error', error) trace.logTrace('outbound', emojic.noGoodWoman, 'Handled error', error)
@@ -379,7 +385,7 @@ class BaseService {
namedParams, namedParams,
transformedQueryParams transformedQueryParams
) )
Joi.assert(serviceData, serviceDataSchema) serviceInstance._validateServiceData(serviceData)
} catch (error) { } catch (error) {
serviceError = error serviceError = error
} }

View File

@@ -192,7 +192,7 @@ describe('BaseService', function() {
}) })
}) })
it('Throws a validation error on invalid data', async function() { context('On invalid data', function() {
class ThrowingService extends DummyService { class ThrowingService extends DummyService {
async handle() { async handle() {
return { return {
@@ -200,19 +200,37 @@ describe('BaseService', function() {
} }
} }
} }
try {
await ThrowingService.invoke( it('Throws a validation error on invalid data', async function() {
{}, try {
{ handleInternalErrors: false }, await ThrowingService.invoke(
{ namedParamA: 'bar.bar.bar' } {},
) { handleInternalErrors: false },
expect.fail('Expected to throw') { namedParamA: 'bar.bar.bar' }
} catch (e) { )
expect(e.name).to.equal('ValidationError') expect.fail('Expected to throw')
expect(e.details.map(({ message }) => message)).to.deep.equal([ } catch (e) {
'"message" is required', expect(e.name).to.equal('ValidationError')
]) expect(e.details.map(({ message }) => message)).to.deep.equal([
} '"message" is required',
])
}
})
// Ensure debuggabillity.
// https://github.com/badges/shields/issues/3784
it('Includes the service class in the stack trace', async function() {
try {
await ThrowingService.invoke(
{},
{ handleInternalErrors: false },
{ namedParamA: 'bar.bar.bar' }
)
expect.fail('Expected to throw')
} catch (e) {
expect(e.stack).to.include('ThrowingService._validateServiceData')
}
})
}) })
}) })