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

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.

Related

How can i get Application_UnhandledException details in silverlight/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.

Is it possible to extract only the meaningful informantion from Exception.Message

This is what I get when I use Exception.Message :
System.Web.Services.Protocols.SoapException: The server can not process the request. ---> System.NullReferenceException: Object reference not set to an instance of an object in . in WebService.ProcessRequestArc... --- End of inner exception stack trace ---
Is it possible to configure a web application so that exceptions only send the part in bold in my example?
Or do you know of any way to extract only that part?
The Message property of an exception does not follow any pattern. In particular, the Message property will be different depending on the current culture settings (language).
But even if you are only concerned about a single language, you should never depend on anything in the Message property. It simply contains whatever the developer who threw the exception thinks you might want to see.
In particular, it does not contain anything that you should display to your users!
I didn't quite understand your problem at first. To avoid seeing the Stack Trace, you simply had have display Server.GetLastError().Message. On further examination I see that your problem is that exceptions are getting wrapped into a HttpException, and the Message from HttpException concatenates the method info with the original exception message.
Solution
In web.config you need to add a custom error section.
<customErrors defaultRedirect="Error.aspx"
mode="On" redirectMode="ResponseRewrite">
In Error.aspx you can do the following to check if it's an HttpException, and if so get the inner exception's message.
var ex = Server.GetLastError();
string message;
if (ex != null)
{
message = ((ex is HttpException || ex is SoapException) && ex.InnerException != null)
? ex.InnerException.Message : ex.Message;
}
else
{
message = "An error has occurred.";
}
Response.Write(message);
On your page you just want to show Server.GetLastError().Message.
Here is the before and after for a divide by zero error:
Before: Default.aspx(4): error CS0020: Division by constant zero
After: Attempted to divide by zero.
For SoapException to actually have the InnerException property not be null, then you need to throw a SoapException with the actual exception inside.
Here are some links from MSDN regarding the customErrors section and error handling:
customErrors Element
Complete Example for Error Handlers

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.

dispalying error returned by stored procedure in .aspx form

i have a stored procedure which i use to insert values in a table...if i implement error handling in it using ##ERROR and if i it returns error in a variable #myError can i display this error in my .aspx form??i m using sql server 2005
thanx....
You can use the InfoMessage event of the SqlConnection to output SQL warnings and information messages to the client. By default the event is only fired for information messages with a severity of less than 10. By setting the FireInfoMessageEventOnUserErrors property of the SqlConnection to true you can trigger the InfoMessage event for errors of severity 11 to 16 instead of throwing an exception and halting execution. By adding an event handler for the InfoMessage event we can output the message to the client.
using (SqlConnection conn = new SqlConnection(connString))
{
conn.Open();
conn.FireInfoMessageEventOnUserErrors = true;
conn.InfoMessage += delegate(object sender, SqlInfoMessageEventArgs e)
{
txtMessage.Text += e.Message;
};
...
}
See: HOW TO: Return Errors and Warnings from a SQL Server Stored Procedure in ADO.NET
Yes you can, but normally you don't want to display system error messages to users - it would be better to display a user friendly message instead.
That being said however, just create a label and set the label's Text property with the value of #myError.
I would recommend using TRY/CATCH in T-SQL instead of ##ERROR. The later is notoriously problematic because is reset after each statement. For more details see
Error Handling in SQL Server – a Background
Implementing Error Handling with Stored Procedures
I much prefer TRY/CATCH, using a procedure template like the one described here: Exception handling and nested transactions. This way an error is raised into your ASP.Net as a SqlException which you can catch, like any other CLR exception.

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