1
votes

There is an Azure function that is triggered when HTML files are placed into Azure blob storage.The function opens the HTML file, and transforms it into JSON. There is a small percentage of triggered files (less than 1%), that result in the following exception:

Microsoft.WindowsAzure.Storage.StorageException

There does happen to be a second function triggered by the placement of the blob that changes the files content type, but I am not sure if this is effecting the first function's ability to also open the file.

What can be done to allow the Azure functions to correctly process the HTML files without throwing this type of exception?

Exception properties:

Message: Exception while executing function: [Function name here] The condition specified using HTTP conditional header(s) is not met.

Exception type: Microsoft.WindowsAzure.Storage.StorageException

Failed method: HtmlAgilityPack.HtmlDocument.Load

Exception type: Microsoft.WindowsAzure.Storage.StorageException

Function 1 (supporting methods, class, and namespace omitted for brevity):

using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using HtmlAgilityPack;
using System.Threading.Tasks;

[FunctionName("Function name")]
public static async Task Run([BlobTrigger("container-name/html/{name}", Connection = "ConnectionString")]Stream myBlob, ILogger log, Binder binder)
{
    var doc = new HtmlDocument();
    doc.Load(myBlob);
    var form = doc.DocumentNode.SelectSingleNode("//form");
    var elements = form.SelectNodes("//input");
    CustomType MyObject = BuildObject(elements);

    var attributes = new Attribute[]
    {
        new BlobAttribute("container-name/json/" + MyObject.ID + ".json"),
        new StorageAccountAttribute("ConnectionString")
    };

    using (var writer = await binder.BindAsync<TextWriter>(attributes))
    {
        writer.Write(BuildJSON(MyObject));
    }

}

Function 2 same trigger but in a different function and it's own .cs file. Class and namespace omitted for brevity:

using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Extensions.Logging;
using Microsoft.WindowsAzure.Storage.Blob;

[FunctionName("Function name")]
public static async Task Run([BlobTrigger("container-name/html/{name}", Connection = "ConnectionString")]ICloudBlob myBlob)
{
    if (myBlob.Properties.ContentType == "text/html; charset=utf-8")
    return;

    myBlob.Properties.ContentType = "text/html; charset=utf-8";
    await myBlob.SetPropertiesAsync();
}
1
why they have to be separate functions?Thiago Custodio
The error comes from the Etag changes. function1 thinks it is stale when loaded on blob.1_1

1 Answers

0
votes

I think your error should appear like this: Funtion1 retrieves the blob, and then function2's operation on the blob causes the change of Etag. Then function1 tries to load the retrieved blob, but finds that the Etag has changed, so it returns to you abnormal.

If the resource is accessed or changed by multiple apps, please have a try to make sure the orginal files are not changed. Otherwise the Etag of the blob will be changed automatically.

Azure Storage blob use 'strong Etag validation'. the content of the two resource representations must be byte-for-byte identical and that all other entity fields (such as Content-Language) are also unchanged.

Please refer to this:https://www.microsoftpressstore.com/articles/article.aspx?p=2224058&seqNum=12