How can i get Application_UnhandledException details in silverlight/ASP.NET - asp.net

private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
{
if (!System.Diagnostics.Debugger.IsAttached)
{
e.Handled = true;
Deployment.Current.Dispatcher.BeginInvoke(delegate { ReportErrorToDOM(e); });
}
}
I have a solution with a silverlight application (that calls a webservice) being hosted in an asp.net application.
If there is any unhanded exception in the application, i want to get as much detail as can be possible e.g the exception message, innerexception details, file where exception occurred, method which was being called.....just like what i would get in a catch block.
So from the Application_UnhandledException event above, how can i get this information from the ApplicationUnhandledExceptionEventArgs e?

e.ExceptionObject.ToString()
is better than the default from the wizard in that it also gives you nested exception names, messages and stack traces.
Method names are included in the stack traces.
File names and line numbers, however, are not retrievable from Silverlight by any method I know of, even when running with elevated privileges.

Related

How can I handle exceptions in WebAPI 2. methods?

In my WebAPI 2.1 application I am processing inserts like this:
[Route("Post")]
public async Task<IHttpActionResult> Post([FromBody]City city)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
try
{
db.Exams.Add(city);
await db.SaveChangesAsync(User, DateTime.UtcNow);
}
catch (Exception ex)
{
var e = ex;
return BadRequest("Error: City not created");
}
return Ok(city);
}
I use something similar for updates and deletes. I think I should do something more meaningfull with
the exceptions but I am not sure where to start with how to handle these. I looked at elmah but it said it deals with unhandled exceptions. Does this mean I should not be catching exceptions like this?
Can someone give me some
pointers as to if what I have is okay and also should I be logging exceptions and how?
What you are doing is not "bad", it's just a bit verbose and won't scale well if you have many try/catch blocks all over your code. When an exception is raised, you decide what to do so, returning a bad request response is fine if it's really a bad request. There are many things you can return, depending on what went wrong. But you have to handle what to do when exceptions are thrown all over your code, so maintaining this logic scattered all over your code can quickly become a problem.
It's better to utilise asp.net web api's exception handling framework. For example, take a look at these articles:
http://www.asp.net/web-api/overview/web-api-routing-and-actions/exception-handling
http://www.asp.net/web-api/overview/web-api-routing-and-actions/web-api-global-error-handling
The idea is to centralise your logic in a global exception handler and to use that as the only place in your code where you have to worry about this. The rest of your code will be throwing exceptions and everything will be coming through your exception handler/filter/etc., depending on what you decide.
For example, I have created my own exception types (e.g. CustomExceptionA, CustomExceptionB, etc.) and when I throw an exception of a type I know exactly how to handle it in one place and perform a certain bit of logic. If I want to change the way I handle a particular exception type, then there's only one place I have to make a change and the rest of the code will be unaffected.
The second article link above also includes a global exception logger to log such exceptions.

How to log exception parameter values

I have a asp.net website.
In this website I have made many function, these function are called inside another function. I want to write all the data that was passed to the function along with the value to a log file.
let us suppose an example
public void MyFunction(int a, int b)
{
try
{
int result=a/b;
}
catch
{
Some Code Here so that I can catch the exception and write into my log file like
/**Function Name: MyFunction**/
/**Parameter a=9;**/
/**b=0;**/
}
}
I have searched for postsharp but it doesnt work with website.
use a try/catch block
i.e.
try {
// call a method
} catch(Exception e) {
// an error occurred, details are in the local variable e
}
Assuming you are using a function/method that is part of the .NET library then you can check the documentation which will list all of the possible exceptions. E.g. See "Exceptions": http://msdn.microsoft.com/en-us/library/b9skfh7s.aspx
You can then use try/catch to catch any exceptions that may be thrown.
Take a look at ELMAH.
It is quite is to install and configure.
You will be up and running in no time.
If you want to log also info about passed in parameters I would just rethrow an exception which contains all this info.
Elmah will record it for you
** EDIT **
Here you have a tutorial on how to get up and running.
I recommend that you use nuget, here is a nice step through:
elmah-using-nuget-what-they-are-and-why-you-should-use-them-part-1/

If an exception is caught on the server side of an update panel, can you see the stack trace somehow?

I'm trying to debug a third party library that is throwing an null reference exception in certain cases, but I am only getting the exception from the javascript side, which doesn't contain the stack trace in the error message.
Is there a value in the scriptmanager or something similar with more information about the exception, or should I be removing the update panels to get at the raw exception?
(Easier said then done, its nested several update panels deep)
Thanks!
Look into ScriptManager.AsyncPostBackError event.
You can do something like this
protected void ScriptManager1_AsyncPostBackError(object sender, AsyncPostBackErrorEventArgs e)
{
//do something with the exception
log(e.Exception.Message);
// show a message to the user.
ScriptManager1.AsyncPostBackErrorMessage =
"An error occurred." + e.Exception.Message;
}
}
You can turn off ajax features temporary by setting EnablePartialRendering property of the ScriptManager to false.

Is there a way of showing variable values in an global ASP.Net exception?

I have a global error trap in the Application_Error method of Global.asax that writes any unhandled exception to a log file.
Is there anyway of reporting the variable names and their values as part of the exception report?
Unless you do something really tricky with Aspect-Oriented Programming, you pretty much need to make sure that you manually introduce any relevant information into the stack trace when exceptions are thrown. For example:
public void DoSomething(int number, string name)
{
try
{
...
}
catch (Exception e)
{
throw new Exception("Error occurred while doing something: " +
new {number, name}, e);
}
}
This way, the number and name will be included in the stack trace when this exception trickles up to the top level.
Edit
After reading David Stratton's answer, I felt the need to expand on this a little. I get the sense that even some very experienced C# programmers haven't learned some of the tricks that I've learned.
First of all, I wanted to point out that the exception-handling system in .NET was designed with the idea of an InnerException specifically for this purpose (providing additional information at various points of the stack trace), and it is not at all hacky to do. However, you should definitely provide the exception as the innerException constructor parameter, rather than appending e.ToString() to the new exception's message.
Secondly, based on various comments and answers I've read on StackOverflow, as well as my own experience, it's best to:
Avoid catching an exception if there's nothing specific you plan to do with it.
When you catch an exception, rethrow it unless you know why the exception was thrown and you're in a scope where you know how to gracefully retreat from what you were trying to do. Simply pretending nothing went wrong is asking for more trouble down the road.
When re-throwing exceptions, either just throw; to preserve the original exception's stack trace, or include the original exception as a new exception's InnerException.
Consistently log exceptions that don't get re-thrown. This will generally only happen at the UI level, so you can tell the user something unexpected happened rather than allowing the program to crash.
Finally, I wanted to mention that the anonymous type declaration syntax is ideal for this kind of thing because it is very concise and it will automatically produce a string that uses the given variable names and values. For example, new {number, name}.ToString() might produce "{ number = 1, name = Test }".
We do this in some cases, but in a roundabout way. We use a try/catch at the granular level and if we want to pass the exception up to the global error handler, we build the error message. For example:
int someCounterValue = 0;
string someStringValue = "Some string we want to track to send to the global error handler."
private void SomeFunction()
{
try
{
someStringValue = "in the try block";
someCounterValue = 1.5 // should thrown an exception
}
catch(Exception ex)
{
throw new Exception("Error in SomeFunction. someStringValue = " + someStringValue + "; someCounterValue = " + someCounterValue.ToString() + "\r\nException details: " + ex.ToString());
}
}
It's a lot of work so we really don't do this very often. Usually our error handling is better handled at the local level but in those very rate cases where you want to pass it off to the global error handler, this is about the only way we've found, since the variables would be out of scope otherwise, and therefore, inaccessible.
An easier/less hack-like option would be to set up a static class in your web app called ErrorLogger or something similar, and just handle the exceptions better locally and pass them up to the global handler ONLY when you can't do it locally.
In my opinion (and in the way we do it here by policy) a global error handler should be used to catch exceptions that you forgot to handler better at a more granular level. It should NOT just be an easy way to be lazy about proper exception handling.
Also it feels like a hack to me, so if anyone has a better option I'd like to know it, too.

Handling Request Validation 'silently'

I'm trying to override the onError event handler of a web form to allow "A potentially dangerous Request.Form value was detected from the client" type errors to be handled within the form rather than ending up at the application level error handler.
I found some sample code like this :
protected override void OnError(EventArgs e)
{
// At this point we have information about the error
HttpContext ctx = HttpContext.Current;
Exception exception = ctx.Server.GetLastError();
string errorInfo =
"<br>Offending URL: " + ctx.Request.Url.ToString() +
"<br>Source: " + exception.Source +
"<br>Message: " + exception.Message +
"<br>Stack trace: " + exception.StackTrace;
ctx.Response.Write(errorInfo);
// --------------------------------------------------
// To let the page finish running we clear the error
// --------------------------------------------------
ctx.Server.ClearError();
base.OnError(e);
}
Which satisfactorily catches the error and writes an error message out to the screen but what I really want to do is to be aware of the error when Page_Load fires and so be able to display a 'normal' error message on the webform.
I'm sure there's a good way to do this but I don't know it ! Suggestions ?
(BTW for various reason I don't want to turn off the checking at either form or app level and neither do I wish to rely on Javascript - thanks)
You actually can catch the error at the page level, but it will kill the page lifecycle. So you have to use a trick to get around it. Example:
public override void ProcessRequest(HttpContext context)
{
try
{
base.ProcessRequest(context);
}
catch(HttpRequestValidationException ex)
{
context.Response.Redirect("HandleValidationError.aspx");
}
}
HandleValidationError.aspx can be anything, including a redirection back to the same page (perhaps with a querystring with information regarding the error, e.g. "ContactForm.aspx?error=Invalid+Request")
I think I understand what you want to do, but I'm afraid it might be impossible. When your ASP.NET page performs a postback, a new thread is created on the server to handle the request. Before your page lifecycle even has a chance to begin, the offending XSS is found and an exception is thrown. Once this exception is thrown, you are "evicted" from the ASP.NET page lifecycle and there is no way to re-enter it. At this point, the only thing you can do on the client side is output the error, or redirect to an error page.
What you seem to want to do is catch the exception, write it out somewhere on the page, and continue with the ASP.NET page lifecycle (i.e. restoring the control tree, restoring viewstate, invoking event handlers, etc). The problem is once an unhandled exception is thrown you no longer have access to the ASP.NET page lifecycle. In this particular case, there is nowhere to put a try/catch block because the exception is thrown internally from the ASP.NET lifecycle before your own code is called.
I know you said you don't want to rely on Javascript, but in this case I think using Javascript is the only way to get the behavior you want. You can still keep server-side validation, just in case your users disable Javascript or type some input that your Javascript doesn't handle.
I don't think you'll be able to handle the error in the Page_load event. In the ASP.NET Page Life cycle validation events occur after the page loads.
Maybe you can add a hidden div (<asp:Panel Visible=false ...) that contains your "normal error message". if the OnError event fires display the error message div.
jason

Resources