Does anyone know why I'm getting this error?
Here is my SendGrid output binding:
{
"bindings": [
{
"name": "docId",
"type": "queueTrigger",
"direction": "in",
"queueName": "movedocument",
"connection": "cpoffice365_STORAGE"
},
{
"type": "sendGrid",
"name": "message",
"apiKey": "<MYSENDGRIDKEY>",
"from": "<MYFROMEMAIL>",
"direction": "out"
}
],
"disabled": false
}
My code compiles, but then it throws this error in the log:
Microsoft.Azure.WebJobs.Host: Error indexing method 'Functions.<MYFUNCTIONAME>'. Microsoft.Azure.WebJobs.Host: '<MYSENDGRIDKEY>' does not resolve to a value.
Statto,
Please make sure you define an app setting (Function app settings > App Settings) with the name matching what you've used for your binding configuration, where the value is your Sendgrid key.
The binding configuration expects that to be an app setting name, not the actual key.
Thanks!
Related
I'm trying to use a filter on an Azure function to look up a row in a table based on an optional route parameter. If the parameter isn't provided, or doesn't match a row, a default row should be returned. This works if I provide a matching value, or a wrong value, I get a row as I expect. If I provide no value at all, I get the following error:
Exception while executing function: Functions.link. Microsoft.Azure.WebJobs.Extensions.Storage: Object reference not set to an instance of an object.
The three key bits (AFAIU) are:
httpTrigger route: "link/{ref?}"
Table filter: "Email eq '{ref}' or Default eq true"
Endpoint URL: https://[subdomain].azurewebsites.net/api/link/(ref)
Is there some way to construct the filter or route so that I get the second clause of the filter when the optional parameter is not provided? Or is there a better way to do this?
My full function.json looks like this:
{
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"route": "link/{ref?}",
"direction": "in",
"name": "req",
"methods": [
"get"
]
},
{
"name": "emailRule",
"type": "table",
"take": "1",
"filter": "Email eq '{ref}' or Default eq true",
"tableName": "RedirectRules",
"connection": "TestStorageConnectionAppSetting",
"direction": "in"
},
{
"type": "http",
"direction": "out",
"name": "res"
}
]
}
Try to use this route "route": "link/{ref=''}", this way you dont have null value but always empty string
I started tinkering with Azure SignalR and ran into a problem with the negiotate trigger.
I followed this official Microsoft guide:
Heres my Code:
local.settings.json
{
"IsEncrypted": false,
"Values": {
"AzureSignalRConnectionString": "Endpoint=https://my.service.signalr.net;AccessKey=myKey=;Version=1.0;",
"FUNCTIONS_WORKER_RUNTIME": "node"
},
"Host": {
"LocalHttpPort": 7071,
"CORS": "*",
"CORSCredentials": true
}
}
function.json
{
"disabled": false,
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"methods": [
"get"
],
"name": "req",
"route": "negotiate"
},
{
"type": "http",
"direction": "out",
"name": "res"
},
{
"type": "SignalRConnectionInfo",
"name": "connectionInfo",
"hubName": "jitsi",
"ConnectionStringSetting": "Endpoint=https://my.service.signalr.net;AccessKey=myKey;Version=1.0;",
"direction": "in"
}
]
}
index.js
module.exports = async function (context, req, connectionInfo) {
context.res.body = connectionInfo;
};
It works fine locally (unfortunately thats where the guide ends). But if I visit the URL of the negotiate http-trigger I get "Internal Server Error 500". Logs contain following output.
2020-04-23T08:47:32 Welcome, you are now connected to log-streaming service. The default timeout is 2 hours. Change the timeout with the App Setting SCM_LOGSTREAM_TIMEOUT (in seconds).
2020-04-23T08:47:52.070 [Information] Executing 'Functions.jitsiNegotiate' (Reason='This function was programmatically called via the host APIs.', Id=2b791d95-3775-47bb-ade1-ac9005929f61)
2020-04-23T08:47:52.238 [Error] Executed 'Functions.jitsiNegotiate' (Failed, Id=2b791d95-3775-47bb-ade1-ac9005929f61)
Unable to resolve the value for property 'SignalRConnectionInfoAttribute.ConnectionStringSetting'. Make sure the setting exists and has a valid value.
As you can see in my code I did provide the ConnectionStringSetting.
Some People suggested it's due to lower/upper case 'C' in ConnectionStringSetting.
Others said to to edit local.settings.json.
None of that had any effect for me and I can't find any useful information on the issue.
EDIT 1:
I set "hubName":"jitsi". With jitsi being the name of my SignalR Service.
As in 'jitsi.service.signalr.net'. I'm not sure if that's correct or not.
Perhaps thats part of the issue?
EDIT 2:
I tried with no value set for ConnectionStringSetting (so that it goes to default).
Gave me same error. I also completely deleted any content of local.settings.json and then re-deployed to see what would happen.
Same behaviour as before.
My guess is The service only uses the file for local usage (hence the name).
So with the local.settings.json being empty theres no place else where I defined the value for AzureSignalRConnectionString.
I did some digging and apparently (according to this thread) you should define it under
'Configuration'->'Application Settings'
So I created a new setting with
name: Azure__SignalR__ConnectionString
value: myMaskedConnectionString
Which resulted in the following error:
The SignalR Service connection string must be set either via an 'AzureSignalRConnectionString' app setting, via an 'AzureSignalRConnectionString' environment variable, or directly in code via SignalROptions.ConnectionString or SignalRConnectionInfoAttribute.ConnectionStringSetting.
I found a resolution to this issue:
I got confused at first and thought the local.settings.json would serve as configuration for the live/non-local version of the function. That's not the case. It's only for local execution (could've guessed by the name of the file)
So the question remains: Where/How can I edit the required settings in the Azure Portal?
Answer:Home -> All Services -> Function-App -> MyFunctionApp -> Platform Features -> Configuration -> Application Settings -> Create New Application Setting
name: AzureSignalRConnectionString
value MyMaskedConnectionString
Then in function.json like this:
{
"disabled": false,
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"methods": [
"get"
],
"name": "req",
"route": "negotiate"
},
{
"type": "http",
"direction": "out",
"name": "res"
},
{
"type": "SignalRConnectionInfo",
"name": "connectionInfo",
"hubName": "jitsi",
"direction": "in",
"connectionStringSetting": "AzureSignalRConnectionString"
}
]
}
With those settings it's working for me now.
In a given Azure Function, I can have 1 or more output bindings. For example, I might have a blob storage output (writing a file blob to storage) and a queue output (pushing a message into a queue).
For example, if I have this very simple Azure function (written in Node.js)...
module.exports = function (context, req) {
context.log('START: Multi-output function.');
context.bindings.outputBlob = "blob-contents";
context.bindings.outputQueueItem = "{'message': 'hello!'}";
context.done();
};
... with the output bindings set up in function.json as follows...
{
"bindings": [
{
"authLevel": "function",
"type": "httpTrigger",
"direction": "in",
"name": "req"
},
{
"type": "http",
"direction": "out",
"name": "res"
},
{
"type": "blob",
"name": "outputBlob",
"path": "outcontainer/{rand-guid}",
"connection": "AzureWebJobsDashboard",
"direction": "out"
},
{
"type": "queue",
"name": "outputQueueItem",
"queueName": "outqueue",
"connection": "AzureWebJobsDashboard",
"direction": "out"
}
],
"disabled": false
}
... when do the two output bindings actually fire, and in which order?
For the when part of the question:
Do they fire at the point where the function sets the output binding? (e.g. the line of code that sets context.bindings.outputBlob)
Do they fire at/after context.done()?
For the order part of the question:
Do they fire in the order they're seen in the code?
Do they fire in the order they're seen in function.json ?
Output bindings fire after the function execution is completed - after context.done().
The order that you set them in the code has no influence on binding executions.
If you can, treat the actual execution order as the implementation detail and do not rely on it. Having said that, if I'm not mistaken, the actual order will be:
Execute all non-queue bindings in order of function.json
Then, execute all queue bindings in order of function.json
UPDATE: based on this issue and this issue I conclude that order is not guaranteed at the moment.
I have the following function definition.
Message type:
type MailboxItem = {
CustomerID: int
AssetID: int
}
Code:
let Run(item: MailboxItem, userNames: string, log: TraceWriter) =
log.Verbose("F# function executing for " + item.AssetID.ToString())
And function.json:
{
"bindings": [
{
"type": "eventHubTrigger",
"name": "item",
"direction": "in",
"path": "eventhubpath",
"connection": <connection>,
"consumerGroup": "$Default"
},
{
"type": "blob",
"name": "userNames",
"path": "blobpath/{CustomerID}-{AssetID}",
"connection": <connection>,
"direction": "in"
}
],
"disabled": false
}
As you can see, I'm using properties of the incoming message to bind an input blob from Blob Storage.
Now, I need to extend my function to access some metadata of the incoming message via EventData class (e.g. sequence number). Is it possible to add EventData parameter but also keep the binding to properties of the message body?
No not currently, unfortunately, though this is a common ask and something we're tracking in our repo here and will hopefully get to soon. Until we do, it is an either/or - you can bind to EventData or your custom POCO.
My Azure Function has two input parameters:
Event Hubs trigger
Blob input binding
I am trying to bind both parameters to custom type (F# record in my case). Binding works fine for the trigger, but not for blog binding, which gives the following error:
Microsoft.Azure.WebJobs.Host: Error indexing method 'Functions.MailboxFanOut'.
Microsoft.Azure.WebJobs.Host: Can't bind Blob to type 'Run+CustomerName'.
Here is the code:
[<CLIMutable>]
type CustomerName = {
UserName: string
}
let Run(item: CustomerName, userNames: CustomerName, log: TraceWriter) =
log.Verbose("F# function executing")
Replacing F# record with a class doesn't help...
Here is the function definition:
{
"bindings": [
{
"type": "eventHubTrigger",
"name": "item",
"direction": "in",
"path": "blabla",
"connection": "eventhubs",
"consumerGroup": "$Default"
},
{
"type": "blob",
"name": "userNames",
"path": "tada/123",
"connection": "foo",
"direction": "in"
}
],
"disabled": false
}
The blob bindings unfortunately don't currently support POCO bindings as you'd expect. We have an open issue in our repo tracking this here.
To work around that, I recommend binding to a Stream, string, or one of the other supported types and doing the deserialization into your POCO type in your method.