ELMAH - Exception Logging without having HttpContext
Asked Answered
C

4

53

I tried this solution with Elmah.XmlFileErrorLog but I'm getting following exception

System.ArgumentNullException was unhandled by user code
  Message="Value cannot be null.\r\nParameter name: context"
  Source="Elmah"
  ParamName="context"
  StackTrace:
       at Elmah.ErrorSignal.FromContext(HttpContext context) in c:\builds\ELMAH\src\Elmah\ErrorSignal.cs:line 67
       at Elmah.ErrorSignal.FromCurrentContext() in c:\builds\ELMAH\src\Elmah\ErrorSignal.cs:line 61
       at ElmahHttpErrorHandler.ProvideFault(Exception error, MessageVersion version, Message& fault) in c:\Myapplication\App_Code\Util\ElmahHttpErrorHandler.cs:line 19
       at System.ServiceModel.Dispatcher.ErrorBehavior.ProvideFault(Exception e, FaultConverter faultConverter, ErrorHandlerFaultInfo& faultInfo)
       at System.ServiceModel.Dispatcher.ErrorBehavior.ProvideMessageFaultCore(MessageRpc& rpc)
       at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessageCleanup(MessageRpc& rpc)
  InnerException: 

Web.Config file

<configSections>
    <section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <section name="exceptionHandling" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Configuration.ExceptionHandlingSettings, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    <sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
        <sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
            <section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
            <sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
                <section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere"/>
                <section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
                <section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
                <section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
            </sectionGroup>
        </sectionGroup>
    </sectionGroup>
  <sectionGroup name="elmah">
    <section name="security" requirePermission="false" type="Elmah.SecuritySectionHandler, Elmah" />
    <section name="errorLog" requirePermission="false" type="Elmah.ErrorLogSectionHandler, Elmah" />
    <section name="errorMail" requirePermission="false" type="Elmah.ErrorMailSectionHandler, Elmah" />
    <section name="errorFilter" requirePermission="false" type="Elmah.ErrorFilterSectionHandler, Elmah" />
  </sectionGroup>
</configSections>
<httpHandlers>
  <add verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />
  <remove verb="*" path="*.asmx"/>
    <add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
    <add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
    <add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false"/>
</httpHandlers>
<httpModules>
    <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
  <add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" />
</httpModules>
...

<elmah>
  <errorLog type="Elmah.XmlFileErrorLog, Elmah" logPath="~/App_Data" />
  <security allowRemoteAccess="1" />
</elmah>

I'm using windows 7. can there be any problem related to it?

UPDATE Note: I'm running WCF service unders ASP.NET. i.e. I've added WCF Service project to solution by Add New Website and then selecting WCF Service template. I'm currently running it from within IDE. Hosting it on IIS also didn't helped though.

Cozmo answered 8/6, 2010 at 12:6 Comment(0)
C
88

I'm answering my own question.

I tried adding following in my web.config

<system.serviceModel>
  <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>

Also decorated my Service with following attribute

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]    
public class CalculatorService : ICalculatorSession    
{
    // Implement calculator service methods
 }

Still no use. Then I got the solution here by which you can use Elmah without HTTPContext. i.e. log errors by writing

Elmah.ErrorLog.GetDefault(null).Log(new Error(ex));

instead of

Elmah.ErrorSignal.FromCurrentContext().Raise(error);
Cozmo answered 28/6, 2010 at 13:0 Comment(3)
This saved me, thanks! One other thing you may want to note. If you are using the SQLErrorLog type, you must specify an applicationName key/value pair in your errorLog tag, otherwise you won't be able to see out of context entries in the log, because a "default" application name gets assigned from the HTTPContext when it's present. Such as <errorLog type="Elmah.SqlErrorLog, Elmah" connectionStringName="ApplicationServices" applicationName="Sysdine"/>Durstin
Thanks @DavidC for the tip. However, anyone know about for emailLog? Haven't looked too much into it, but my quick spike shows that even with applicationName specified, emailLog never sends it out (works with ...FromCurrentContext()...). Although I should point out that I'm running it in an async task.Erubescent
So there's no ambiguity, the Error constructor referenced above is Elmah.Error. May want to qualify that.Underlinen
C
38

Thanks everyone, here is my ErrorHelper class I came up with to manually log errors on websites and in WCF services, windows services, etc:

    public static class ErrorHelper
{
    /// <summary>
    /// Manually log an exception to Elmah.  This is very useful for the agents that try/catch all the errors.
    /// 
    /// In order for this to work elmah must be setup in the web.config/app.config file
    /// </summary>
    /// <param name="ex"></param>
    public static void LogErrorManually(Exception ex)
    {
        if (HttpContext.Current != null)//website is logging the error
        {                
            var elmahCon = Elmah.ErrorSignal.FromCurrentContext();
            elmahCon.Raise(ex);
        }
        else//non website, probably an agent
        {                
            var elmahCon = Elmah.ErrorLog.GetDefault(null);
            elmahCon.Log(new Elmah.Error(ex));
        }
    }
}
Continuant answered 6/6, 2012 at 19:19 Comment(2)
For anyone else who tries this and get an "Invalid argument" error, make sure you add a reference to System.Web in your service / windows app.Clance
The reference to System.Web saved me! Thanks @ClanceGallego
I
1

Are you running this code within ASP.NET?

Seems like the HttpContext is null and this is causing the Elmah code to throw the exception - the method Elmah.ErrorSignal.FromCurrentContext() would pass HttpContext.Current from what I remember (been a while since looked into it) to the Elmah.ErrorSignal.FromContext(HttpContext context) method, and this seems to be null, which would not normally be the case in ASP.NET hosted stuff.

Another possibility is that this is occurring outside a request to the server so the HttpContext might be null.

Inappreciative answered 8/6, 2010 at 13:42 Comment(2)
I'm running WCF service as unders ASP.NET. i.e. I've added WCF Service project to solution by Add New Website and then selecting WCF Service template. I'm currently running it from within IDE. Can it resolve if I host it on IIS?Cozmo
I'm running it on IIS and having the same problemAdversity
A
1

The only stable solution I could find is to remove the web.config attribute and use the service behavior attribute they use in Exception Logging for WCF Services using ELMAH

Adversity answered 10/8, 2010 at 14:13 Comment(3)
+1 Thanks for the effort you took in order to solve a question already marked answer on a temporary solution.Cozmo
I was having the same problem myself so no worriesAdversity
That said you hardly get much information from the HTTP Request itself that you need when debugging a WCF service so I'm not sure it's worth the effort.Adversity

© 2022 - 2024 — McMap. All rights reserved.