Azure / azure-webjobs-sdk

Azure WebJobs SDK
MIT License
738 stars 358 forks source link

Exception logging: report inner exception #2156

Open lmolkova opened 5 years ago

lmolkova commented 5 years ago

I have a function that throws:

        [FunctionName("TimerTriggerCSharp")]
        [Singleton]
        public static void Run([TimerTrigger("0 */1 * * * *")]TimerInfo myTimer, ILogger log)
        {
            throw new Exception("veryuniqueerror");
        }

The exception that is passed to logger is


  | Name | Value | Type
-- | -- | -- | --
◢ | exception | {Microsoft.Azure.WebJobs.Host.FunctionInvocationException: Exception while executing function: TimerTriggerCSharp ---> System.Exception: veryuniqueerror    at SampleHost.Functions.Run(TimerInfo myTimer, ILogger log) in C:\repo\azure-webjobs-sdk\sample\SampleHost\Functions.cs:line 31    at lambda_method(Closure , Functions , Object[] )    at Microsoft.Azure.WebJobs.Host.Executors.VoidMethodInvoker`2.InvokeAsync(TReflected instance, Object[] arguments) in C:\repo\azure-webjobs-sdk\src\Microsoft.Azure.WebJobs.Host\Executors\VoidMethodInvoker.cs:line 20    at Microsoft.Azure.WebJobs.Host.Executors.FunctionInvoker`2.InvokeAsync(Object instance, Object[] arguments) in C:\repo\azure-webjobs-sdk\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionInvoker.cs:line 52    at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.InvokeAsync(IFunctionInvoker invoker, ParameterHelper parameterHelper, CancellationTokenSource timeoutTokenSource, CancellationTokenSource functionCancellationTokenSource, Boolean throwOnTimeout, TimeSpan timerInterval, IFunctionInstance instance) in C:\repo\azure-webjobs-sdk\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 584    at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithWatchersAsync(IFunctionInstanceEx instance, ParameterHelper parameterHelper, ILogger logger, CancellationTokenSource functionCancellationTokenSource) in C:\repo\azure-webjobs-sdk\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 531    at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(IFunctionInstanceEx instance, ParameterHelper parameterHelper, IFunctionOutputDefinition outputDefinition, ILogger logger, CancellationTokenSource functionCancellationTokenSource) in C:\repo\azure-webjobs-sdk\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 467    at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(IFunctionInstanceEx instance, FunctionStartedMessage message, FunctionInstanceLogEntry instanceLogEntry, ParameterHelper parameterHelper, ILogger logger, CancellationToken cancellationToken) in C:\repo\azure-webjobs-sdk\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 277    --- End of inner exception stack trace ---    at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(IFunctionInstanceEx instance, FunctionStartedMessage message, FunctionInstanceLogEntry instanceLogEntry, ParameterHelper parameterHelper, ILogger logger, CancellationToken cancellationToken) in C:\repo\azure-webjobs-sdk\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 321    at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.TryExecuteAsyncCore(IFunctionInstanceEx functionInstance, CancellationToken cancellationToken) in C:\repo\azure-webjobs-sdk\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 117} | System.Exception {Microsoft.Azure.WebJobs.Host.FunctionInvocationException}
  | ▶ Data | {System.Collections.ListDictionaryInternal} | System.Collections.IDictionary {System.Collections.ListDictionaryInternal}
  | HResult | -2146233088 | int
  | Handled | false | bool
  | HelpLink | null | string
  | ▶ InnerException | {System.Exception: veryuniqueerror    at SampleHost.Functions.Run(TimerInfo myTimer, ILogger log) in C:\repo\azure-webjobs-sdk\sample\SampleHost\Functions.cs:line 31    at lambda_method(Closure , Functions , Object[] )    at Microsoft.Azure.WebJobs.Host.Executors.VoidMethodInvoker`2.InvokeAsync(TReflected instance, Object[] arguments) in C:\repo\azure-webjobs-sdk\src\Microsoft.Azure.WebJobs.Host\Executors\VoidMethodInvoker.cs:line 20    at Microsoft.Azure.WebJobs.Host.Executors.FunctionInvoker`2.InvokeAsync(Object instance, Object[] arguments) in C:\repo\azure-webjobs-sdk\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionInvoker.cs:line 52    at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.InvokeAsync(IFunctionInvoker invoker, ParameterHelper parameterHelper, CancellationTokenSource timeoutTokenSource, CancellationTokenSource functionCancellationTokenSource, Boolean throwOnTimeout, TimeSpan timerInterval, IFunctionInstance instance) in C:\repo\azure-webjobs-sdk\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 584    at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithWatchersAsync(IFunctionInstanceEx instance, ParameterHelper parameterHelper, ILogger logger, CancellationTokenSource functionCancellationTokenSource) in C:\repo\azure-webjobs-sdk\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 531    at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(IFunctionInstanceEx instance, ParameterHelper parameterHelper, IFunctionOutputDefinition outputDefinition, ILogger logger, CancellationTokenSource functionCancellationTokenSource) in C:\repo\azure-webjobs-sdk\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 467    at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(IFunctionInstanceEx instance, FunctionStartedMessage message, FunctionInstanceLogEntry instanceLogEntry, ParameterHelper parameterHelper, ILogger logger, CancellationToken cancellationToken) in C:\repo\azure-webjobs-sdk\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 277} | System.Exception
  | ▶ InstanceId | {5d24d861-5c35-46a5-b614-6ff1fcff6a32} | System.Guid
  | Message | "Exception while executing function: TimerTriggerCSharp" | string
  | MethodName | "SampleHost.Functions.Run" | string
  | Source | "System.Private.CoreLib" | string
  | StackTrace | "   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(IFunctionInstanceEx instance, FunctionStartedMessage message, FunctionInstanceLogEntry instanceLogEntry, ParameterHelper parameterHelper, ILogger logger, CancellationToken cancellationToken) in C:\\repo\\azure-webjobs-sdk\\src\\Microsoft.Azure.WebJobs.Host\\Executors\\FunctionExecutor.cs:line 321\r\n   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.TryExecuteAsyncCore(IFunctionInstanceEx functionInstance, CancellationToken cancellationToken) in C:\\repo\\azure-webjobs-sdk\\src\\Microsoft.Azure.WebJobs.Host\\Executors\\FunctionExecutor.cs:line 117" | string
  | ▶ TargetSite | {Void Throw()} | System.Reflection.MethodBase {System.Reflection.RuntimeMethodInfo}
  | ▶ Static members |   |  
  | ▶ Non-Public members |   |  

The outer exception is handled " at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(IFunctionInstanceEx instance, FunctionStartedMessage message, FunctionInstanceLogEntry instanceLogEntry, ParameterHelper parameterHelper, ILogger logger, CancellationToken cancellationToken) in C:\\repo\\azure-webjobs-sdk\\src\\Microsoft.Azure.WebJobs.Host\\Executors\\FunctionExecutor.cs:line 321\r\n at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.TryExecuteAsyncCore(IFunctionInstanceEx functionInstance, CancellationToken cancellationToken) in C:\\repo\\azure-webjobs-sdk\\src\\Microsoft.Azure.WebJobs.Host\\Executors\\FunctionExecutor.cs:line 117"

which has not much to do with user code, while exception that function actually threw is inner exception.

  1. Does it make sense to provide inner exception to the logger instead of the outer one?
  2. For the non.NET functions, this is even more complicated as a full exception wit hstack trace is set on the .NET Exception (pic below), while .NET stack trace does not make much sense.

image

lmolkova commented 5 years ago

cc @brettsam