From d2ef74dace820d5e16ab44c9ce47ec8e18cc0162 Mon Sep 17 00:00:00 2001 From: Eric Jizba Date: Tue, 30 Jan 2024 11:20:41 -0800 Subject: [PATCH 1/2] Make error message even better for missing binding --- src/InvocationModel.ts | 9 ++++++++- test/InvocationModel.test.ts | 31 +++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/InvocationModel.ts b/src/InvocationModel.ts index 7dd49f1..1630e60 100644 --- a/src/InvocationModel.ts +++ b/src/InvocationModel.ts @@ -20,6 +20,7 @@ import { fromRpcTypedData } from './converters/fromRpcTypedData'; import { toCamelCaseValue } from './converters/toCamelCase'; import { toRpcHttp } from './converters/toRpcHttp'; import { toRpcTypedData } from './converters/toRpcTypedData'; +import { AzFuncSystemError } from './errors'; import { InvocationContext } from './InvocationContext'; import { isHttpTrigger, isTimerTrigger, isTrigger } from './utils/isTrigger'; import { isDefined, nonNullProp, nonNullValue } from './utils/nonNull'; @@ -62,7 +63,13 @@ export class InvocationModel implements coreTypes.InvocationModel { const bindingName = nonNullProp(binding, 'name'); let input: unknown = fromRpcTypedData(binding.data); - const bindingType = nonNullProp(this.#bindings, bindingName).type; + const rpcBinding = this.#bindings[bindingName]; + if (!rpcBinding) { + throw new AzFuncSystemError( + `Failed to find binding "${bindingName}" in bindings "${Object.keys(this.#bindings).join()}".` + ); + } + const bindingType = rpcBinding.type; if (isTimerTrigger(bindingType)) { input = toCamelCaseValue(input); } diff --git a/test/InvocationModel.test.ts b/test/InvocationModel.test.ts index ed4d233..af65018 100644 --- a/test/InvocationModel.test.ts +++ b/test/InvocationModel.test.ts @@ -79,5 +79,36 @@ describe('InvocationModel', () => { const response = await model.getResponse(context, undefined); expect(response).to.deep.equal({ invocationId: 'testInvocId', outputData: [], returnValue: undefined }); }); + + // https://github.com/Azure/azure-functions-nodejs-library/issues/210 + it('Missing binding', async () => { + const model = new InvocationModel({ + invocationId: 'testInvocId', + metadata: { + name: 'testFuncName', + bindings: { + httpTrigger1: { + type: 'httpTrigger', + direction: 'in', + }, + $return: { + type: 'http', + direction: 'out', + }, + }, + }, + request: { + inputData: [ + { + name: 'httpTriggerMissing', + }, + ], + }, + log: testLog, + }); + await expect(model.getArguments()).to.be.rejectedWith( + 'Failed to find binding "httpTriggerMissing" in bindings "httpTrigger1,$return".' + ); + }); }); }); From c6d96adb8af6c82989fa5e17ab3a10059c8f4136 Mon Sep 17 00:00:00 2001 From: Eric Jizba Date: Tue, 30 Jan 2024 14:11:22 -0800 Subject: [PATCH 2/2] nit --- src/InvocationModel.ts | 4 +++- test/InvocationModel.test.ts | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/InvocationModel.ts b/src/InvocationModel.ts index 1630e60..50b2919 100644 --- a/src/InvocationModel.ts +++ b/src/InvocationModel.ts @@ -66,7 +66,9 @@ export class InvocationModel implements coreTypes.InvocationModel { const rpcBinding = this.#bindings[bindingName]; if (!rpcBinding) { throw new AzFuncSystemError( - `Failed to find binding "${bindingName}" in bindings "${Object.keys(this.#bindings).join()}".` + `Failed to find binding "${bindingName}" in bindings "${Object.keys(this.#bindings).join( + ', ' + )}".` ); } const bindingType = rpcBinding.type; diff --git a/test/InvocationModel.test.ts b/test/InvocationModel.test.ts index af65018..0ac1c52 100644 --- a/test/InvocationModel.test.ts +++ b/test/InvocationModel.test.ts @@ -107,7 +107,7 @@ describe('InvocationModel', () => { log: testLog, }); await expect(model.getArguments()).to.be.rejectedWith( - 'Failed to find binding "httpTriggerMissing" in bindings "httpTrigger1,$return".' + 'Failed to find binding "httpTriggerMissing" in bindings "httpTrigger1, $return".' ); }); });