Search code examples
node.jsazureazure-functionsazure-storage-queues

Queue triggered Azure function throws exception when Queue message is created with the Azure Storage Node SDK


I use the Azure Storage Node SDK to add a message to an Azure Storage Queue. Following the official exampel, my code looks like this:

const AzureStorage = require('azure-storage');
const queueService = AzureStorage.createQueueService();

queueService.createMessage('taskqueue', 'Hello world!', function (error) {
  if (!error) {
    // Message inserted
  }
});

This adds a message to the taskqueue queue, which in turn triggers a Queue triggered Azure Function built with Node. When the Azure Function receives the message, it throws the following exception:

Exception while executing function: Functions.Function2. 
Microsoft.Azure.WebJobs.Host: Exception binding parameter 'queuedMessage'. 
mscorlib: The input is not a valid Base-64 string as it contains a non-base 
64 character, more than two padding characters, or an illegal character 
among the padding characters.

Solution

  • After a fair amount of Googling, when I couldn't find anything in the official documentation, I found this excellent post.

    Apparently there is an inconsistency between how messages are encoded (by default) via Azure Storage Node SDK and how they are decoded via Queue triggered Node functions. According to above referenced post, the Azure Storage SDK defaults to using the TextXmlQueueMessageEncoder, while the Azure Function expects the message to be encoded with the TextBase64QueueMessageEncoder.

    New @azure/storage-queue lib

    The inconsistency remain in the new queue library as well. In this library I haven't been able to find a built-in way to switch the encoder, but manually base64-enconding the string does the trick:

    const { QueueServiceClient } = require("@azure/storage-queue")
    
    const base64Encode = (str) => Buffer.from(str).toString('base64')
    
    const queueServiceClient = new QueueServiceClient(...)
    queueServiceClient.getQueueClient('myqueue').sendMessage(base64Encode('Hello World!'))
    

    Old azure-storage lib

    In the old library, manually overriding the default encoder solves the problem.

    const AzureStorage = require('azure-storage');
    const QueueMessageEncoder = AzureStorage.QueueMessageEncoder;
    
    const queueService = AzureStorage.createQueueService();
    queueService.messageEncoder = new QueueMessageEncoder.TextBase64QueueMessageEncoder();
    queueService.createMessage('taskqueue', 'Hello world!', function(error) {
      if (!error) {
        // Message inserted
      }
    });