Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error when trying to access Azure Function

I have an anonymous function on Azure, successfully deployed (.netstandard 2.0), using Microsoft.NET.Sdk.Functions (1.0.13), but for some reason suddenly it stopped working and when I call it the response is:

<ApiErrorModel xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Microsoft.Azure.WebJobs.Script.WebHost.Models">
<Arguments xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" i:nil="true"/>
<ErrorCode>0</ErrorCode>
<ErrorDetails i:nil="true"/>
<Id>91fab400-3447-4913-878f-715d9d4ab46b</Id>
<Message>
An error has occurred. For more information, please check the logs for error ID 91fab400-3447-4913-878f-715d9d4ab46b
</Message>
<RequestId>0fb00298-733d-4d88-9e73-c328d024e1bb</RequestId>
<StatusCode>InternalServerError</StatusCode>
</ApiErrorModel>

How to figure that out?

EDIT: When I start AF environment locally and run the function it works as expected, without any issues, although what i see in console is a message in red:

enter image description here

and searching for it, stumbled across this GitHub post: https://github.com/Azure/azure-functions-host/issues/2765

where I noticed this part:

@m-demydiuk noticed that azure function works with this error in the console. So this red error doesn't break function on the local machine. But I am afraid it may cause any problems in other environments.

and it bothers me. Can it be the problem?

I use a lib with a version that do not match my target framework, but again locally works fine, and also it was working fine before on Azure

enter image description here

My host version is "Version=2.0.11651.0"

This is the entire function:

public static class Function1
    {
        [FunctionName("HTML2IMG")]
        public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)]HttpRequest req, TraceWriter log)
        {
            string url = req.Query["url"];

            byte[] EncodedData = Convert.FromBase64String(url);
            string DecodedURL = Encoding.UTF8.GetString(EncodedData);

            string requestBody = new StreamReader(req.Body).ReadToEnd();
            dynamic data = JsonConvert.DeserializeObject(requestBody);
            DecodedURL = DecodedURL ?? data?.name;
            var api = new HtmlToPdfOrImage.Api("9123314e-219c-342d-a763-0a3dsdf8ad21", "vmZ31vyg");

            var ApiResult = api.Convert(new Uri($"{DecodedURL}"), new HtmlToPdfOrImage.GenerateSettings() { OutputType = HtmlToPdfOrImage.OutputType.Image });

            string BlobName = Guid.NewGuid().ToString("n");
            string ImageURL = await CreateBlob($"{BlobName}.png", (byte[])ApiResult.model, log);
            var Result = new HttpResponseMessage(HttpStatusCode.OK);
            var oJSON = new { url = ImageURL, hash = BlobName };
            var jsonToReturn = JsonConvert.SerializeObject(oJSON);

            Result.Content = new StringContent(jsonToReturn);
            Result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");

            return Result;
        }

        private async static Task<string> CreateBlob(string name, byte[] data, TraceWriter log)
        {
            string accessKey = "xxx";
            string accountName = "xxx";
            string connectionString = "DefaultEndpointsProtocol=https;AccountName=" + accountName + ";AccountKey=" + accessKey + ";EndpointSuffix=core.windows.net";
            CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString);
            CloudBlobClient client = storageAccount.CreateCloudBlobClient();
            CloudBlobContainer container = client.GetContainerReference("images");

            await container.CreateIfNotExistsAsync();

            BlobContainerPermissions permissions = await container.GetPermissionsAsync();
            permissions.PublicAccess = BlobContainerPublicAccessType.Container;
            await container.SetPermissionsAsync(permissions);

            CloudBlockBlob blob = container.GetBlockBlobReference(name);
            blob.Properties.ContentType = "image/png";

            using (Stream stream = new MemoryStream(data))
            {
                await blob.UploadFromStreamAsync(stream);
            }

            return blob.Uri.AbsoluteUri;
        }

DOUBLE EDIT: I created empty V2 .net core AF in VS and published it straight away -> i get the same error... I even updated the Microsoft.NET.Sdk.Function to the latest 1.0.14 instead of 1.0.13 and still get the same error. Obviously something in Azure or Visual Studio (15.7.5) is broken?!?!

like image 363
nmrlqa4 Avatar asked May 21 '26 02:05

nmrlqa4


1 Answers

Solution

On Azure portal, go to Function app settings check your Runtime Version. It is probably Runtime version: 1.0.11913.0 (~1) on your side. This is the problem. Change FUNCTIONS_EXTENSION_VERSION to beta in Application settings and your code should work on Azure.

Explanation

You create a v2 function as your local host version is 2.0.11651.0. So the function runtime should also be beta 2.x(latest is 2.0.11933.0) online.

When you published functions from VS before, you probably saw this prompt

enter image description here

You may have chosen No so that you got the error.

Note that if we publish through CI/CD like VSTS or Git, such notification is not available. So we need to make sure those configurations are set correctly.

Suggestions

As you can see your local host version is 2.0.11651, which is lower than 2.0.11933 on Azure. I do recommend you to update Azure Functions and Web Jobs Tools(on VS menus, Tools->Extensions and Updates) to latest(15.0.40617.0) for VS to consume latest function runtime.

As for your code, I recommend you to create images container and set its public access level manually on portal since this process only requires executing once.

Then we can use blob output bindings.

  1. Add StorageConnection to Application settings with storage connection string. If your images container is in the storage account used by function app (AzureWebJobsStorge in Application settings), ignore this step and delete Connection parameter below, because bindings use that storage account by default.

  2. Add blob output bindings

    public static async Task<HttpResponseMessage> Run(...,TraceWriter log,
            [Blob("images", FileAccess.Read, Connection = "StorageConnection")] CloudBlobContainer container)
    
  3. Change CreateBlob method

    private async static Task<string> CreateBlob(string name, byte[] data, TraceWriter log, CloudBlobContainer container)
    {
        CloudBlockBlob blob = container.GetBlockBlobReference(name);
        blob.Properties.ContentType = "image/png";
    
        using (Stream stream = new MemoryStream(data))
        {
            await blob.UploadFromStreamAsync(stream);
        }
    
        return blob.Uri.AbsoluteUri;
    }
    
like image 107
Jerry Liu Avatar answered May 22 '26 17:05

Jerry Liu



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!