Skip to content

Commit

Permalink
Improvements to core error handling/reporting
Browse files Browse the repository at this point in the history
  • Loading branch information
mathewc committed Mar 18, 2016
1 parent 7fafb1d commit 333d05a
Show file tree
Hide file tree
Showing 23 changed files with 322 additions and 133 deletions.
5 changes: 5 additions & 0 deletions WebJobs.Script.sln
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DocumentDB-Node", "Document
ProjectSection(SolutionItems) = preProject
sample\DocumentDB-Node\function.json = sample\DocumentDB-Node\function.json
sample\DocumentDB-Node\index.js = sample\DocumentDB-Node\index.js
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "QueueTrigger-CSharp", "QueueTrigger-CSharp", "{C11EBC32-877C-4EBA-85B2-14720555BB71}"
ProjectSection(SolutionItems) = preProject
sample\QueueTrigger-CSharp\function.json = sample\QueueTrigger-CSharp\function.json
sample\QueueTrigger-CSharp\run.csx = sample\QueueTrigger-CSharp\run.csx
EndProjectSection
EndProject
Global
Expand Down Expand Up @@ -246,5 +250,6 @@ Global
{87E44645-EA02-4F12-8C3E-820B5710292D} = {FF9C0818-30D3-437A-A62D-7A61CA44F459}
{437EB182-8CB9-42BD-9019-E5F6E69D1DB3} = {FF9C0818-30D3-437A-A62D-7A61CA44F459}
{8811DCFB-1023-4577-AB9C-B4F191200082} = {FF9C0818-30D3-437A-A62D-7A61CA44F459}
{C11EBC32-877C-4EBA-85B2-14720555BB71} = {FF9C0818-30D3-437A-A62D-7A61CA44F459}
EndGlobalSection
EndGlobal
16 changes: 16 additions & 0 deletions sample/QueueTrigger-CSharp/function.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"bindings": [
{
"name": "message",
"type": "queueTrigger",
"direction": "in",
"queueName": "samples-csharp"
},
{
"type": "blob",
"name": "result",
"direction": "out",
"path": "samples-output-csharp/{Id}"
}
]
}
17 changes: 17 additions & 0 deletions sample/QueueTrigger-CSharp/run.csx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs.Host;

public static void Run(Message message, out string result, TraceWriter log)
{
log.Verbose($"C# Queue trigger function processed message: {message.Id}");

result = message.Value;
}

public class Message
{
public string Id { get; set; }
public string Value { get; set; }
}
9 changes: 5 additions & 4 deletions src/WebJobs.Script.Host/WebJobs.Script.Host.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<UseVSHostingProcess>false</UseVSHostingProcess>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
Expand Down Expand Up @@ -68,7 +69,7 @@
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Azure.WebJobs, Version=1.1.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.WebJobs.Core.1.1.2-alpha-10267\lib\net45\Microsoft.Azure.WebJobs.dll</HintPath>
<HintPath>..\..\packages\Microsoft.Azure.WebJobs.Core.1.1.2-alpha-10271\lib\net45\Microsoft.Azure.WebJobs.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Azure.WebJobs.Extensions, Version=1.0.2.0, Culture=neutral, processorArchitecture=MSIL">
Expand All @@ -84,15 +85,15 @@
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Azure.WebJobs.Extensions.SendGrid, Version=1.0.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.WebJobs.Extensions.SendGrid.1.0.2-alpha-10251\lib\net45\Microsoft.Azure.WebJobs.Extensions.SendGrid.dll</HintPath>
<HintPath>..\..\packages\Microsoft.Azure.WebJobs.Extensions.SendGrid.1.0.2-alpha-10252\lib\net45\Microsoft.Azure.WebJobs.Extensions.SendGrid.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Azure.WebJobs.Host, Version=1.1.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.WebJobs.1.1.2-alpha-10267\lib\net45\Microsoft.Azure.WebJobs.Host.dll</HintPath>
<HintPath>..\..\packages\Microsoft.Azure.WebJobs.1.1.2-alpha-10271\lib\net45\Microsoft.Azure.WebJobs.Host.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Azure.WebJobs.ServiceBus, Version=1.1.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.WebJobs.ServiceBus.1.1.2-alpha-10267\lib\net45\Microsoft.Azure.WebJobs.ServiceBus.dll</HintPath>
<HintPath>..\..\packages\Microsoft.Azure.WebJobs.ServiceBus.1.1.2-alpha-10271\lib\net45\Microsoft.Azure.WebJobs.ServiceBus.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Data.Edm, Version=5.6.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
Expand Down
8 changes: 4 additions & 4 deletions src/WebJobs.Script.Host/packages.config
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@
<package id="Microsoft.Azure.DocumentDB" version="1.5.3" targetFramework="net46" />
<package id="Microsoft.Azure.Mobile.Client" version="2.0.1" targetFramework="net46" />
<package id="Microsoft.Azure.ServiceBus.EventProcessorHost" version="1.4.0" targetFramework="net46" />
<package id="Microsoft.Azure.WebJobs" version="1.1.2-alpha-10267" targetFramework="net46" />
<package id="Microsoft.Azure.WebJobs.Core" version="1.1.2-alpha-10267" targetFramework="net46" />
<package id="Microsoft.Azure.WebJobs" version="1.1.2-alpha-10271" targetFramework="net46" />
<package id="Microsoft.Azure.WebJobs.Core" version="1.1.2-alpha-10271" targetFramework="net46" />
<package id="Microsoft.Azure.WebJobs.Extensions" version="1.0.2-alpha-10252" targetFramework="net46" />
<package id="Microsoft.Azure.WebJobs.Extensions.DocumentDB" version="1.0.0-alpha-10252" targetFramework="net46" />
<package id="Microsoft.Azure.WebJobs.Extensions.EasyTables" version="1.0.0-alpha-10252" targetFramework="net46" />
<package id="Microsoft.Azure.WebJobs.Extensions.SendGrid" version="1.0.2-alpha-10251" targetFramework="net46" />
<package id="Microsoft.Azure.WebJobs.ServiceBus" version="1.1.2-alpha-10267" targetFramework="net46" />
<package id="Microsoft.Azure.WebJobs.Extensions.SendGrid" version="1.0.2-alpha-10252" targetFramework="net46" />
<package id="Microsoft.Azure.WebJobs.ServiceBus" version="1.1.2-alpha-10271" targetFramework="net46" />
<package id="Microsoft.Bcl" version="1.1.10" targetFramework="net46" />
<package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="net46" />
<package id="Microsoft.Data.Edm" version="5.6.2" targetFramework="net45" />
Expand Down
5 changes: 2 additions & 3 deletions src/WebJobs.Script.WebHost/App_Start/WebApiConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,9 @@ public static void Register(HttpConfiguration config, WebHostSettings settings =

private static void PrependFoldersToEnvironmentPath()
{
string home = Environment.GetEnvironmentVariable("HOME");

// Only do this when %HOME% is defined (normally on Azure)
if (!String.IsNullOrEmpty("HOME"))
string home = Environment.GetEnvironmentVariable("HOME");
if (!string.IsNullOrEmpty(home))
{
// Create the tools folder if it doesn't exist
string toolsPath = Path.Combine(home, @"site\tools");
Expand Down
8 changes: 4 additions & 4 deletions src/WebJobs.Script.WebHost/WebJobs.Script.WebHost.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Azure.WebJobs, Version=1.1.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.WebJobs.Core.1.1.2-alpha-10267\lib\net45\Microsoft.Azure.WebJobs.dll</HintPath>
<HintPath>..\..\packages\Microsoft.Azure.WebJobs.Core.1.1.2-alpha-10271\lib\net45\Microsoft.Azure.WebJobs.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Azure.WebJobs.Extensions, Version=1.0.2.0, Culture=neutral, processorArchitecture=MSIL">
Expand All @@ -140,15 +140,15 @@
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Azure.WebJobs.Extensions.SendGrid, Version=1.0.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.WebJobs.Extensions.SendGrid.1.0.2-alpha-10251\lib\net45\Microsoft.Azure.WebJobs.Extensions.SendGrid.dll</HintPath>
<HintPath>..\..\packages\Microsoft.Azure.WebJobs.Extensions.SendGrid.1.0.2-alpha-10252\lib\net45\Microsoft.Azure.WebJobs.Extensions.SendGrid.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Azure.WebJobs.Host, Version=1.1.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.WebJobs.1.1.2-alpha-10267\lib\net45\Microsoft.Azure.WebJobs.Host.dll</HintPath>
<HintPath>..\..\packages\Microsoft.Azure.WebJobs.1.1.2-alpha-10271\lib\net45\Microsoft.Azure.WebJobs.Host.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Azure.WebJobs.ServiceBus, Version=1.1.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.WebJobs.ServiceBus.1.1.2-alpha-10267\lib\net45\Microsoft.Azure.WebJobs.ServiceBus.dll</HintPath>
<HintPath>..\..\packages\Microsoft.Azure.WebJobs.ServiceBus.1.1.2-alpha-10271\lib\net45\Microsoft.Azure.WebJobs.ServiceBus.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
Expand Down
8 changes: 4 additions & 4 deletions src/WebJobs.Script.WebHost/packages.config
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@
<package id="Microsoft.AspNet.WebHooks.Receivers.WordPress" version="1.2.0-beta6" targetFramework="net45" />
<package id="Microsoft.Azure.DocumentDB" version="1.5.3" targetFramework="net46" />
<package id="Microsoft.Azure.Mobile.Client" version="2.0.1" targetFramework="net46" />
<package id="Microsoft.Azure.WebJobs" version="1.1.2-alpha-10267" targetFramework="net46" />
<package id="Microsoft.Azure.WebJobs.Core" version="1.1.2-alpha-10267" targetFramework="net46" />
<package id="Microsoft.Azure.WebJobs" version="1.1.2-alpha-10271" targetFramework="net46" />
<package id="Microsoft.Azure.WebJobs.Core" version="1.1.2-alpha-10271" targetFramework="net46" />
<package id="Microsoft.Azure.WebJobs.Extensions" version="1.0.2-alpha-10252" targetFramework="net46" />
<package id="Microsoft.Azure.WebJobs.Extensions.DocumentDB" version="1.0.0-alpha-10252" targetFramework="net46" />
<package id="Microsoft.Azure.WebJobs.Extensions.EasyTables" version="1.0.0-alpha-10252" targetFramework="net46" />
<package id="Microsoft.Azure.WebJobs.Extensions.SendGrid" version="1.0.2-alpha-10251" targetFramework="net46" />
<package id="Microsoft.Azure.WebJobs.ServiceBus" version="1.1.2-alpha-10267" targetFramework="net46" />
<package id="Microsoft.Azure.WebJobs.Extensions.SendGrid" version="1.0.2-alpha-10252" targetFramework="net46" />
<package id="Microsoft.Azure.WebJobs.ServiceBus" version="1.1.2-alpha-10271" targetFramework="net46" />
<package id="Microsoft.Bcl" version="1.1.10" targetFramework="net46" />
<package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="net46" />
<package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="1.0.0" targetFramework="net452" />
Expand Down
49 changes: 29 additions & 20 deletions src/WebJobs.Script/Description/CSharp/CSharpFunctionInvoker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -171,21 +171,24 @@ private void RestorePackages()

public override async Task Invoke(object[] parameters)
{
// Separate system parameters from the actual method parameters
object[] originalParameters = parameters;
MethodInfo function = await GetFunctionTargetAsync();
int actualParameterCount = function.GetParameters().Length;
object[] systemParameters = parameters.Skip(actualParameterCount).ToArray();
parameters = parameters.Take(actualParameterCount).ToArray();

ExecutionContext functionExecutionContext = (ExecutionContext)systemParameters[0];
string invocationId = functionExecutionContext.InvocationId.ToString();

FunctionStartedEvent startedEvent = new FunctionStartedEvent(Metadata);
_metrics.BeginEvent(startedEvent);
FunctionStartedEvent startedEvent = null;
string invocationId = null;

try
{
// Separate system parameters from the actual method parameters
object[] originalParameters = parameters;
MethodInfo function = await GetFunctionTargetAsync();
int actualParameterCount = function.GetParameters().Length;
object[] systemParameters = parameters.Skip(actualParameterCount).ToArray();
parameters = parameters.Take(actualParameterCount).ToArray();

ExecutionContext functionExecutionContext = (ExecutionContext)systemParameters[0];
invocationId = functionExecutionContext.InvocationId.ToString();

startedEvent = new FunctionStartedEvent(Metadata);
_metrics.BeginEvent(startedEvent);

TraceWriter.Verbose(string.Format("Function started (Id={0})", invocationId));

parameters = ProcessInputParameters(parameters);
Expand All @@ -211,19 +214,25 @@ public override async Task Invoke(object[] parameters)

TraceWriter.Verbose(string.Format("Function completed (Success, Id={0})", invocationId));
}
catch (Exception ex)
catch
{
TraceWriter.Error(ex.Message, ex is CompilationErrorException ? null : ex);

startedEvent.Success = false;
TraceWriter.Error(ex.Message, ex);

TraceWriter.Verbose(string.Format("Function completed (Failure, Id={0})", invocationId));
if (startedEvent != null)
{
startedEvent.Success = false;
TraceWriter.Verbose(string.Format("Function completed (Failure, Id={0})", invocationId));
}
else
{
TraceWriter.Verbose("Function completed (Failure)");
}
throw;
}
finally
{
_metrics.EndEvent(startedEvent);
if (startedEvent != null)
{
_metrics.EndEvent(startedEvent);
}
}
}

Expand Down
14 changes: 14 additions & 0 deletions src/WebJobs.Script/Description/IFunctionInvoker.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;
using System.Threading.Tasks;

namespace Microsoft.Azure.WebJobs.Script.Description
{
public interface IFunctionInvoker
{
/// <summary>
/// Invoke the function using the specified parameters.
/// </summary>
/// <param name="parameters">The parameters.</param>
/// <returns>A <see cref="Task"/> for the invocation.</returns>
Task Invoke(object[] parameters);

/// <summary>
/// This method is called by the host when invocation exceptions occur
/// outside of the invocation. This allows the invoker to inspect/log the
/// exception as necessary.
/// </summary>
/// <param name="ex">The <see cref="Exception"/> that occurred.</param>
void OnError(Exception ex);
}
}
3 changes: 1 addition & 2 deletions src/WebJobs.Script/Description/NodeFunctionInvoker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,9 @@ public override async Task Invoke(object[] parameters)

TraceWriter.Verbose(string.Format("Function completed (Success, Id={0})", invocationId));
}
catch (Exception ex)
catch
{
startedEvent.Success = false;
TraceWriter.Error(ex.Message, ex);
TraceWriter.Verbose(string.Format("Function completed (Failure, Id={0})", invocationId));
throw;
}
Expand Down
4 changes: 2 additions & 2 deletions src/WebJobs.Script/Description/ScriptFunctionInvoker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,9 @@ internal async Task ExecuteScriptAsync(string path, string arguments, object[] i
{
startedEvent.Success = false;

string error = process.StandardError.ReadToEnd();
TraceWriter.Error(error);
TraceWriter.Verbose(string.Format("Function completed (Failure, Id={0})", invocationId));

string error = process.StandardError.ReadToEnd();
throw new ApplicationException(error);
}

Expand Down
11 changes: 11 additions & 0 deletions src/WebJobs.Script/Description/ScriptFunctionInvokerBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,17 @@ private static TraceWriter CreateTraceWriter(ScriptHostConfiguration scriptConfi
return NullTraceWriter.Instance;
}

/// <summary>
/// All unhandled invocation exceptions will flow through this method.
/// We format the error and write it to our function specific <see cref="TraceWriter"/>.
/// </summary>
/// <param name="ex"></param>
public virtual void OnError(Exception ex)
{
string error = Utility.FlattenException(ex);
TraceWriter.Error(error);
}

protected void InitializeFileWatcherIfEnabled()
{
if (Host.ScriptConfig.FileWatchingEnabled)
Expand Down
4 changes: 3 additions & 1 deletion src/WebJobs.Script/GlobalSuppressions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,6 @@
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Scope = "member", Target = "Microsoft.Azure.WebJobs.Script.ScriptHostConfiguration.#Functions")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.Azure.WebJobs.Script.Description.FunctionValueLoader.#Create(System.Func`2<System.Threading.CancellationToken,System.Reflection.MethodInfo>)")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.Azure.WebJobs.Script.FileTraceWriter.#.ctor(System.String,System.Diagnostics.TraceLevel)", Justification = "Disposed in IDisposable implementation.")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.Azure.WebJobs.Script.Description.ScriptFunctionInvokerBase.#CreateTraceWriter(Microsoft.Azure.WebJobs.Script.ScriptHostConfiguration,System.String)", Justification = "Disposed in IDisposable implementation.")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.Azure.WebJobs.Script.Description.ScriptFunctionInvokerBase.#CreateTraceWriter(Microsoft.Azure.WebJobs.Script.ScriptHostConfiguration,System.String)", Justification = "Disposed in IDisposable implementation.")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Scope = "member", Target = "Microsoft.Azure.WebJobs.Script.ScriptHost.#ApplyConfiguration(Newtonsoft.Json.Linq.JObject,Microsoft.Azure.WebJobs.Script.ScriptHostConfiguration)")]
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "Microsoft.Azure.WebJobs.Script.ScriptHost.#Initialize()")]
Loading

0 comments on commit 333d05a

Please sign in to comment.