I've got a pretty custom SharePoint 2010 Server solution. We have a custom HttpModule setup for error handling (relevant code provided below):
public class ErrorHandlerModule : IHttpModule
{
public void Application_Error(object sender, EventArgs e)
{
HttpContext Context = HttpContext.Current;
Exception exception;
for (exception = Context.Server.GetLastError(); exception.InnerException != null; exception = exception.InnerException) { }
//Log and redirect user to custom error page as appropriate - code excluded for clarity/conciseness
}
}
We also have the following relevant items specified in the web.config:
<SharePoint>
<SafeMode CallStack="true" ></SafeMode>
</SharePoint>
<system.web>
<customErrors mode="On" defaultRedirect="~/_layouts/custom/ErrorHandler.aspx" />
</system.web>
<system.webServer>
<modules>
<add name="CustomErrorHandler" preCondition="integratedMode" type="OurApp.Common.HttpModules.ErrorHandlerModule, OurApp.Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=abc123..." />
</modules>
</system.webServer>
We've inherited the code/setup, and see noted that "CallStack='true'" is not ideal (except for development environments). We are looking to change this attribute setting back to 'false' for all non-development environments, however, we notice that in doing so, the code in our custom event handler is not able to obtain a reference to valid exception via the "Context.Server.GetLastError()" method call. When we switch it back to CallStack='true', we are able to get a valid Exception object reference using the same "Context.Server.GetLastError()" method call. The example scenario where I "raise" an error that is handled by this is in a custom List Item event receiver where I set the Cancel and Error Message properties (for example in an ItemAdding or ItemUpdating event):
public override void ItemUpdating(SPItemEventProperties properties)
{
properties.Cancel = true;
properties.ErrorMessage = "An error that we control happened.";
return;
}
It seems odd to me that a "SharePoint specific" attribute in the web.config would change the behavior of the core ASP.NET Server.GetLastError() method call.
UPDATE: I've also tried with an Application page (_layouts) that inherits from the base System.Web.UI.Page, rather than any of the SharePoint specific Layouts page base classes, and threw exception in Page_Load. I am seeing the same behavior - with callstack="true" I can access the exception from Context.Server.GetLastError() in the error handling module, however, with callstack="false" (the ideal setting value), I am not able to get a valid exception reference.
public class ErrorTest : System.Web.UI.Page
{
protected override void OnLoad(EventArgs e)
{
throw new Exception("blah");
}
}
END UPDATE
My understanding of the CallStack attribute is that it affects whether error details are surfaced in the UI, not the API. Am I understanding this incorrectly? Should I expect the behavior to be changed in the underlying API?