1
votes

I am implementing an Azure function that reads a file from the blob storage. The problem is that the Azure function returns a 500 http response error when the file does not exist in the blob storage. This is quite an undesired behaviour and I'd like to handle the exception and return a 404 error. Is it possible with bindings or should I move to SDK to access the blob storage

function.json

{
  "scriptFile": "__init__.py",
  "entryPoint": "app",
  "bindings": [
    {
      "name": "req",
      "direction": "in",
      "methods": [ "get" ],
      "route": "ReadFile/{filename:alpha?}",
      "type": "httpTrigger"
    },
    {
      "name": "blobstream",
      "type": "blob",
      "path": "files/{filename}",
      "connection": "STRATOS_SAMPLE_BLOB_STORAGE_CONNECTION_STRING",
      "direction": "in"
    },
    {
      "name": "$return",
      "direction": "out",
      "type": "http"
    }
  ]
}

__init__.py

import logging
import azure.functions as func
import json
import pandas as pd
import io


def app(req: func.HttpRequest, blobstream: func.InputStream) -> func.HttpResponse:
    filename = req.route_params.get('filename'):

...

Logs:

2020-10-15T07:34:58.967 [Error] Executed 'Functions.read_file' (Failed, Id=3c5f1534-fb65-4909-946f-e3a415197215)Result: FailureException: AttributeError: 'NoneType' object has no attribute 'type'Stack:   File "/azure-functions-host/workers/python/3.8/LINUX/X64/azure_functions_worker/dispatcher.py", line 297, in _handle__invocation_requestargs[pb.name] = bindings.from_incoming_proto(File "/azure-functions-host/workers/python/3.8/LINUX/X64/azure_functions_worker/bindings/meta.py", line 63, in from_incoming_protoreturn binding.decode(datum, trigger_metadata=metadata)File "/azure-functions-host/workers/python/3.8/LINUX/X64/azure/functions/blob.py", line 78, in decodedata_type = data.type
2020-10-15T07:34:58.982 [Error] Executed 'Functions.read_file' (Failed, Id=3c5f1534-fb65-4909-946f-e3a415197215)Result: FailureException: AttributeError: 'NoneType' object has no attribute 'type'Stack:   File "/azure-functions-host/workers/python/3.8/LINUX/X64/azure_functions_worker/dispatcher.py", line 297, in _handle__invocation_requestargs[pb.name] = bindings.from_incoming_proto(File "/azure-functions-host/workers/python/3.8/LINUX/X64/azure_functions_worker/bindings/meta.py", line 63, in from_incoming_protoreturn binding.decode(datum, trigger_metadata=metadata)File "/azure-functions-host/workers/python/3.8/LINUX/X64/azure/functions/blob.py", line 78, in decodedata_type = data.type
2020-10-15T07:34:59.001732137Z [41m[30mfail[39m[22m[49m: Function.read_file[0]
2020-10-15T07:34:59.001776638Z       Executed 'Functions.read_file' (Failed, Id=3c5f1534-fb65-4909-946f-e3a415197215)
2020-10-15T07:34:59.001788839Z Microsoft.Azure.WebJobs.Host.FunctionInvocationException: Exception while executing function: Functions.read_file
2020-10-15T07:34:59.001854541Z  ---> Microsoft.Azure.WebJobs.Script.Workers.Rpc.RpcException: Result: Failure
2020-10-15T07:34:59.001860041Z Exception: AttributeError: 'NoneType' object has no attribute 'type'
2020-10-15T07:34:59.001920843Z Stack:   File "/azure-functions-host/workers/python/3.8/LINUX/X64/azure_functions_worker/dispatcher.py", line 297, in _handle__invocation_request
2020-10-15T07:34:59.001926443Z     args[pb.name] = bindings.from_incoming_proto(
2020-10-15T07:34:59.001929743Z   File "/azure-functions-host/workers/python/3.8/LINUX/X64/azure_functions_worker/bindings/meta.py", line 63, in from_incoming_proto
2020-10-15T07:34:59.001970645Z     return binding.decode(datum, trigger_metadata=metadata)
2020-10-15T07:34:59.001982945Z   File "/azure-functions-host/workers/python/3.8/LINUX/X64/azure/functions/blob.py", line 78, in decode
2020-10-15T07:34:59.001987145Z     data_type = data.type
2020-10-15T07:34:59.001990145Z
2020-10-15T07:34:59.002043347Z    at Microsoft.Azure.WebJobs.Script.Description.WorkerFunctionInvoker.InvokeCore(Object[] parameters, FunctionInvocationContext context) in /src/azure-functions-host/src/WebJobs.Script/Description/Workers/WorkerFunctionInvoker.cs:line 85
2020-10-15T07:34:59.002086349Z    at Microsoft.Azure.WebJobs.Script.Description.FunctionInvokerBase.Invoke(Object[] parameters) in /src/azure-functions-host/src/WebJobs.Script/Description/FunctionInvokerBase.cs:line 85
2020-10-15T07:34:59.002091449Z    at Microsoft.Azure.WebJobs.Script.Description.FunctionGenerator.Coerce[T](Task`1 src) in /src/azure-functions-host/src/WebJobs.Script/Description/FunctionGenerator.cs:line 225
2020-10-15T07:34:59.002155151Z    at Microsoft.Azure.WebJobs.Host.Executors.FunctionInvoker`2.InvokeAsync(Object instance, Object[] arguments) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionInvoker.cs:line 52
2020-10-15T07:34:59.002246954Z    at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.InvokeAsync(IFunctionInvoker invoker, ParameterHelper parameterHelper, CancellationTokenSource timeoutTokenSource, CancellationTokenSource functionCancellationTokenSource, Boolean throwOnTimeout, TimeSpan timerInterval, IFunctionInstance instance) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 587
2020-10-15T07:34:59.002296856Z    at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithWatchersAsync(IFunctionInstanceEx instance, ParameterHelper parameterHelper, ILogger logger, CancellationTokenSource functionCancellationTokenSource) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 532
2020-10-15T07:34:59.002400059Z    at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(IFunctionInstanceEx instance, ParameterHelper parameterHelper, IFunctionOutputDefinition outputDefinition, ILogger logger, CancellationTokenSource functionCancellationTokenSource) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 470
2020-10-15T07:34:59.002505363Z    at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(IFunctionInstanceEx instance, FunctionStartedMessage message, FunctionInstanceLogEntry instanceLogEntry, ParameterHelper parameterHelper, ILogger logger, CancellationToken cancellationToken) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 278
2020-10-15T07:34:59.002515663Z    --- End of inner exception stack trace ---
2020-10-15T07:34:59.002926676Z    at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(IFunctionInstanceEx instance, FunctionStartedMessage message, FunctionInstanceLogEntry instanceLogEntry, ParameterHelper parameterHelper, ILogger logger, CancellationToken cancellationToken) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 325
2020-10-15T07:34:59.003123383Z    at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.TryExecuteAsyncCore(IFunctionInstanceEx functionInstance, CancellationToken cancellationToken) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 117
2020-10-15T07:34:59.069209972Z [41m[30mfail[39m[22m[49m: Host.Results[0]
2020-10-15T07:34:59.069229273Z Microsoft.Azure.WebJobs.Host.FunctionInvocationException: Exception while executing function: Functions.read_file
2020-10-15T07:34:59.069233173Z  ---> Microsoft.Azure.WebJobs.Script.Workers.Rpc.RpcException: Result: Failure
2020-10-15T07:34:59.069300475Z Exception: AttributeError: 'NoneType' object has no attribute 'type'
2020-10-15T07:34:59.069305475Z Stack:   File "/azure-functions-host/workers/python/3.8/LINUX/X64/azure_functions_worker/dispatcher.py", line 297, in _handle__invocation_request
2020-10-15T07:34:59.069308975Z     args[pb.name] = bindings.from_incoming_proto(
2020-10-15T07:34:59.069360577Z   File "/azure-functions-host/workers/python/3.8/LINUX/X64/azure_functions_worker/bindings/meta.py", line 63, in from_incoming_proto
2020-10-15T07:34:59.069365777Z     return binding.decode(datum, trigger_metadata=metadata)
2020-10-15T07:34:59.069412379Z   File "/azure-functions-host/workers/python/3.8/LINUX/X64/azure/functions/blob.py", line 78, in decode
2020-10-15T07:34:59.069417379Z     data_type = data.type
2020-10-15T07:34:59.069420479Z
2020-10-15T07:34:59.069468581Z    at Microsoft.Azure.WebJobs.Script.Description.WorkerFunctionInvoker.InvokeCore(Object[] parameters, FunctionInvocationContext context) in /src/azure-functions-host/src/WebJobs.Script/Description/Workers/WorkerFunctionInvoker.cs:line 85
2020-10-15T07:34:59.069473881Z    at Microsoft.Azure.WebJobs.Script.Description.FunctionInvokerBase.Invoke(Object[] parameters) in /src/azure-functions-host/src/WebJobs.Script/Description/FunctionInvokerBase.cs:line 85
2020-10-15T07:34:59.069518982Z    at Microsoft.Azure.WebJobs.Script.Description.FunctionGenerator.Coerce[T](Task`1 src) in /src/azure-functions-host/src/WebJobs.Script/Description/FunctionGenerator.cs:line 225
2020-10-15T07:34:59.069561684Z    at Microsoft.Azure.WebJobs.Host.Executors.FunctionInvoker`2.InvokeAsync(Object instance, Object[] arguments) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionInvoker.cs:line 52
2020-10-15T07:34:59.069645886Z    at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.InvokeAsync(IFunctionInvoker invoker, ParameterHelper parameterHelper, CancellationTokenSource timeoutTokenSource, CancellationTokenSource functionCancellationTokenSource, Boolean throwOnTimeout, TimeSpan timerInterval, IFunctionInstance instance) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 587
2020-10-15T07:34:59.069720789Z    at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithWatchersAsync(IFunctionInstanceEx instance, ParameterHelper parameterHelper, ILogger logger, CancellationTokenSource functionCancellationTokenSource) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 532
2020-10-15T07:34:59.069760890Z    at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(IFunctionInstanceEx instance, ParameterHelper parameterHelper, IFunctionOutputDefinition outputDefinition, ILogger logger, CancellationTokenSource functionCancellationTokenSource) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 470
2020-10-15T07:34:59.069877694Z    at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(IFunctionInstanceEx instance, FunctionStartedMessage message, FunctionInstanceLogEntry instanceLogEntry, ParameterHelper parameterHelper, ILogger logger, CancellationToken cancellationToken) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 278
2020-10-15T07:34:59.069883894Z    --- End of inner exception stack trace ---
2020-10-15T07:34:59.069981998Z    at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(IFunctionInstanceEx instance, FunctionStartedMessage message, FunctionInstanceLogEntry instanceLogEntry, ParameterHelper parameterHelper, ILogger logger, CancellationToken cancellationToken) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 325
2020-10-15T07:34:59.070037899Z    at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.TryExecuteAsyncCore(IFunctionInstanceEx functionInstance, CancellationToken cancellationToken) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 117
1

1 Answers

3
votes

Unfortunately there is no way in Binding to gracefully handle blob does not exist scenario at this moment. There are open github issues:

  1. https://github.com/Azure/azure-functions-python-worker/issues/670
  2. https://github.com/Azure/azure-webjobs-sdk/issues/1326

I think you are pretty much left with moving to SDK to access blob instead of binding if you want to handle it.