Elmah Raise() records inner exception - c#

I'm trying to raise an exception using Elmah like this:
try
{
Foo();
}
catch (WebException ex)
{
var nex = new Exception("Foo failed", ex);
Elmah.ErrorSignal.FromCurrentContext().Raise(nex);
}
However, what Elmah records is the inner exception ex, not my new wrapper exception nex, i.e. the resulting database record has:
Type = "System.Net.WebException", Message = "The remote server returned an error: (400) Bad Request."
rather than, as I would expect:
Type = "System.Exception", Message = "Foo failed"
What on earth's going on?

ELMAH shows the type of the inner exception on the list of exceptions (/elmah.axd). If you click the Details link next to the error message, I'm pretty sure you'll see something like this:
System.Exception: Foo failed ---> System.Net.WebException
I just created a test project and verified that this is the experienced behaviour.
Edit: As discussed in comments, use of the base exception in the Type and Message fields appears to be the intended behavior.

Related

How to catch "A potentially dangerous Request.Path value was detected from the client (:)" to avoid web role crash?

My MVC 5 web application running on Azure Cloud Service crashed with an unhandled exception "A potentially dangerous Request.Path value was detected from the client (:)".
The cause for this crash was some third party (maybe malicious) hit my endpoints with url:
http://myExampleHost.com/m:443/templates
The colon in the url cannot pass the path validation.
Some answers (A potentially dangerous Request.Path value was detected from the client (*)) suggest change the validate rules. However, out of security concerns, we may not want to compromise on this.
The ideal behavior for it that: we catch the exception, log it and return some error messages without crashing. How should we do that?
A more general question on this would be: how to catch an exception before the request hits controllers in MVC?
The ideal behavior for it that: we catch the exception, log it and return some error messages without crashing. How should we do that?
Per my understanding, you could leverage the Application_Error event to capture unhandled exception(s) within ASP.NET. Here is my test, you could refer to it:
protected void Application_Error()
{
HttpContext httpContext = HttpContext.Current;
var exception=Server.GetLastError();
var httpException = exception as HttpException ?? new HttpException(500, "Internal Server Error", exception);
var jsonResponse = new
{
Message = exception.Message,
StatusCode = httpException.GetHttpCode(),
StackTrace=httpException.StackTrace
};
httpContext.Response.ContentType = "application/json";
httpContext.Response.ContentEncoding = Encoding.UTF8;
httpContext.Response.Write(JsonConvert.SerializeObject(jsonResponse));
httpContext.Response.End();
}
Note: You could also redirect to a specific error page.
Moreover, you could leverage the customErrors in web.config and catch the error page for the specific HTTP error code. Also, you could check the HTTP status code under the Application_EndRequest event and write your custom response, details you could refer to this similar issue. Additionally, I would recommend you follow Demystifying ASP.NET MVC 5 Error Pages and Error Logging for more details about error handling.

Passing exception data between two applications

I don't know if this has been already answered or not. But, I am unable to find the example or cause of this problem.
Application 1:
try
{
//Read request and check for the request header element from the soap request
//validating request and salt
...here it might gets failed.
_requestValidationService.ValidateRequest();
}
catch (Exception ex)
{
ex.Data.Add("Exception", "test");
throw ex;
}
Application 2:
catch (Exception ex)
{
string aa = Convert.ToString(ex.Data["Exception"]);
throw ex;
}
I don't know what I am missing here. But aa seems to be always empty and ex.Data.Count is always zero.
I just want to pass one code between two applications without adding new class of an exception.
Note: These two applications are wcf calls.
[EDIT1]
Application 1 validate request is the IDispatchMessageInspector AfterReceiveRequest
Exceptions are not propagated to clients from a WCF service. Instead, a SOAP Fault (assuming you are using SOAP) will be sent to the client.
You can include exception details in the SOAP Fault, but in general it is not recommended to do so in production.
IMHO a better approach is to implement an IErrorHandler that provides the Fault with whatever data you want to send to the client, and also gives you the opportunity to log the exception server-side.
You can then catch FaultException on the client and have access to the data added by your custom error handler.
The exception class is designed by one throw / catch pair. If you should add any additional information to a cached exception, use the inner exception feature by the rethrow technique:
catch (Exception ex)
{
ErrorHandling.WriteError(ex);
var newEx = new MyException("Additional message", ex) // wrap the original exception instance.
newEx.Data.Add("Exception", "test");
throw newEx;
}
After catching the wrapper exception you can find the original exception in the InnerException property. Another advantage that the original and wrapper exceptions contain their own stack trace so it is easier to find location of error source.

Exception handling in ASP.NET (C#) web services

I was looking for a way to transfer the exception message in web services of my asp.net application to the ajax error callback function.
All I could find was catching an exception thrown from web service into a C# code but i am calling my service from ajax code and not a C# code. I want something more than the HTTP status codes returned.
Here is catch block of my Service code:
catch (Exception ex)
{
var fault = new GenericFault { Message = ex.Message, Operation = "" };
throw new FaultException<GenericFault>(fault);
}
}
And here is my ajax error callback:
error: function (err) {
alert("The server encountered an error, please resubmit your request. If the problem persists, contact your administrator.");
return 'error occured';
}
I have already tried throwing web fault exception but that also didn't serve the purpose as only the HTTP status code gets passed.
Found an answer. The trick lies in throwing right exception.
As the error caught in the callback error function sees the details in xhr object.
So you need to throw the HttpException passing with it status code and string message.
catch block should look something like:
catch (Exception ex)
{
throw new HttpException(500, ex.Message);
}
then your ajax callback will get the ex.message that you are passing from here:
error: function (err) {
alert("The Detailed server error is "+err.responseJSON.Message);
return 'error occured';
}

How do I get an HTTP status code from TTransport exceptions?

I'm using a thrift HttpClient (C#) to make web requests to a web server I've set up, and if that server returns something other than 200 (or 202 I imagine), my request throws a TTransport exception.
I'd like to respond to this exception based on the specific status code returned, but I don't see anything that exposes the status code in the exception's interface. Have I missed something? I know the exception message contains the status code, but I'd rather not have to parse that message to get at the status code.
If the server encounters an processing error, the recommended method is not throwing a HTTP 500. Instead, the server should signal this by means of an exception. Consider the following Thrift IDL:
exception MyProcessingError
{
1: string reason
2: string errorDetails
3: string recommendedAction
}
service FooBar {
void ProcessPayments( 1: double amount; 2: string receiver)
throws (1: MyProcessingError mpe)
}
Similar to args and struct fields, multiple exception types can be declared. The client can catch these exceptions as usual:
try
{
client.ProcessPayments( 47.11, "Dagobert");
}
catch (MyProcessingError e)
{
// process exception
}
Remarks
The server may only throw exceptions that are declared in the IDL for
the particular call.
Furthermore, oneway calls never return any value, thus no
exceptions either.

Good idea to catch HttpException?

I have the following error in my output.aspx page sometimes:
Exception Details: System.Web.HttpException: Request timed out.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[HttpException (0x80004005): Request timed out.]
Is it a good idea to catch this exception? Where do I do that as my output.aspx.cs has a Page_Load and that function calls RunTable(). Should I put a try catch block around that functions content?
catch exception at application level
void Application_Error(object sender, EventArgs e)
{
// Code that runs when an unhandled error occurs
// Get the exception object.
Exception exc = Server.GetLastError();
// Handle HTTP errors
if (exc.GetType() == typeof(HttpException))
{
// The Complete Error Handling Example generates
// some errors using URLs with "NoCatch" in them;
// ignore these here to simulate what would happen
// if a global.asax handler were not implemented.
if (exc.Message.Contains("NoCatch") || exc.Message.Contains("maxUrlLength"))
return;
//Redirect HTTP errors to HttpError page
Server.Transfer("HttpErrorPage.aspx");
}
// For other kinds of errors give the user some information
// but stay on the default page
Response.Write("<h2>Global Page Error</h2>\n");
Response.Write(
"<p>" + exc.Message + "</p>\n");
Response.Write("Return to the <a href='Default.aspx'>" +
"Default Page</a>\n");
// Log the exception and notify system operators
ExceptionUtility.LogException(exc, "DefaultPage");
ExceptionUtility.NotifySystemOps(exc);
// Clear the error from the server
Server.ClearError();
}

Categories