How to catch unhandled exceptions in custom controls - vb.net

Is there anything similar to the MyApplication_UnhandledException for an user control in VB?
I would like to have a central point where to catch all unhandled exceptions of a user control, without propagating the exception to the application that uses the user control.
I made some test raising an exception in a method of my user control where there is no try/catch code (of course in the true project all methods have a try/catch block).
The exception was caught by MyApplication_UnhandledException event of the application using the user control.
But this is too "far" from the point where the exception happens and in worst case the user should restart the application.
I would like to realize a behaviour for the user control in order that if the user control fails, the exception is not propagated till the application, but just caught at user control level.
Any suggestion? Thank you.
Edit: I forgot to tell that I am talking about WinForm

No, there really isn't. There is an exception handler for the forms threads, but this is also global (i.e. all forms participate).
Your only real option is to add appropriate try/catch blocks throughout.

Is the InnerException of that Exception not null? Sometimes it goes down a few levels, but you can recursively iterate until you find the inner-most InnerException and log that ErrorMessage & StackTrace.

Related

when it is correct purpose of exceptions

I am studying OOP, and I did not understood the concept of exception.
What are the correct uses of exceptions?
Why use exceptions when you already know a possible exception?
For example, I have seen a code sample where the programmer needed to access a file, and had an exception in case the file does not exist. Something like "catch(fileDoesNotExist e)".
Why not use an if to verify before take the action? And use exception only for not known issues, for logging or error messages.
The idea behind the concept of exception was to decouple the error handling code from the "normal" behaviour flow control. That lets to manage/handle the exception further up the call stack.
Historically, with structured language, error handling code (file opening error,...) was mixed within the "business" application code. It was also painful to improve the code in order to manage new error codes.
What are the correct uses of exceptions?
If it is not normal that your file doesn't exist or cannot be opened => it is considered as an exceptional situation => exception => exception handler
Why use exceptions when you already know a possible exception?
To decouple the business application code from the error handling. That eases source code readibility and maintenance.
Exception:
Exception is that interrupt(break) the normal flow of the program.It's thrown at runtime.
Exception Handling
Exception Handling is a mechanism to handle runtime errors such as ClassNotFound, IO, SQL, Remote etc
In java there are mainly two types of exception that checked and unchecked.Other than Error is there
Hierarchy of Exception classes in Java
Why use exceptions when you already know a possible exception?
basically exception handling use to mainly,we assuming in that our particular code will occur some(NullPointerException,ArrayIndexOutOfBoundsException etc..)exception.If we not Handle that,program will break.Actually that Exception it may or may not will happen.But so we need to handle normal flow of the program it occurred or not.Otherwise after that particular code section not executing.

Is there a way to get the last thrown exception outside of a try/catch block?

Edit:
To all answerers and commenters: Please focus on providing the solution I request rather than offer ways to refactor it. The code provided below is a very condensed example for the sake of brevity. I've already stated below that this type of code exists in 20 or 30 places throughout the app and that I am choosing not to move/merge/refactor any of that code if a simpler solution exists.
Original Question:
First, here's brief run-down: We have an app that was developed by an offshore team. The purpose of this application is to run nightly maintenance on various database tables. It is a WinForms app, but it acts more like a console app as all it does is 1) execute a single method in Form1_Load and then 2) call End to shut down the program.
The problem is that the error email notification doesn't work, so I have been charged with the task of fixing it. Consider this code:
Try
'This inner Try/Catch is actually code in another method
Try
'Run some code here
Catch ex As Exception
'Errors are logged silently to text file here
End Try
Catch ex As Exception
'Code to email exception details is here
End Try
The problem is that an exception is thrown and handled in the inner Try/Catch. Because of this, there's no exception to be handled in the outer Try/Catch, hence why no email notification is being sent.
Someone might say to just add Throw ex in the inner Catch, but keep in mind that there are about 20 or 30 places in the code where exceptions are handled like this. The decision I am making is to just get it working for now and not undergo that kind of development effort. Therefore, I seek a way to somehow acquire the last exception thrown by the application. This way, I can add a Finally block to the outer Try/Catch and do something like this:
Finally
If Not Application.GetLastException() is Nothing Then
SendErrorEmail(Application.GetLastException())
End If
End Try
So if I understand this correctly, your application catches all exceptions and logs them silently to a file.
You want to change the behavior so that when the program ends you get the last exception thrown, if any, and send an email with that exception detail. But the last exception thrown isn't stored anywhere.
And you want to change this behavior without modifying the code that handles the exceptions.
That can't be done. How do you expect to change the program's behavior without changing the program's behavior? What you ask is impossible. (And, no, not even Yoda would be able to pull this particular X-wing out of the swamp.)
There is no runtime property that automatically saves the last exception thrown.
You will have to make some modification to the code that catches the exceptions. You say that the code takes this general format:
Try
'This inner Try/Catch is actually code in another method
Try
'Run some code here
Catch ex As Exception
'Errors are logged silently to text file here
End Try
Catch ex As Exception
'Code to email exception details is here
End Try
I take it that the problem is in the inner Catch block. Seems to me that if there's common code to log the errors to a text file, that code should be in a separate method. If it is, then modify that method to save the last exception in a property that can be accessed by your GetLastException method. If there isn't a common method that handles the exception logging then you'll have to make the change at every place.
The commenters are correct: A general "catch all exceptions" is almost always a bad idea. Especially when the "handling" consists of logging and continuing. When you catch some random exception, you have no idea what the state of your program is. It's very likely that the data is corrupt and the program's state is unstable. "Log and continue" just makes the problem worse, and can lead to all kinds of interesting side effects like data corruption, infinite loops, deadlock, etc.
Your best course of action here is to refactor the code. Actually, the best course would be to send it back to the offshore developers and tell them to do it right. But that's probably too much to ask.
I'm quite late to this party but you could try this rather ugly way of doing things.
Firstly extend the Application class by adding a LastException property and a GetLastException function, see here for details.
Secondly add a line to each of the inner Catch blocks and set the LastExcepotion property:
Application.LastException = ex
There you go, no need to refactor all that offshore code.

NHibernate Error reporting advice

This is not so much a problem as advice on best practice really. I am writing an ASP.Net MVC application, and in my DAL i am using NHibernate, but what do you do if an exception is thrown in your DAL?
Do you catch the exception in the DAL, log the error and then re-throw the exception?
Do you not even attempt to catch exeptions at all and use the Application_Error() method in the global.asax as a generic catch all?
Do you catch the exception log it and return a bool to the controller indicating a success or failure, or do you do something completly different?
Leading on from this how then do you handle informing the users? Do you show a generic "Error Occured - please try again" type page or do you show a more informative error?
This is exactly one of those 'it depends' questions. This is what I do:
Handle all exceptions in Application_Error (or similar sink-like location)
If the exception is base for business logic - say cannot have duplicates, just catch it and act upon it.
If it is an infrastructure exception and there is a good chance you can fix it by retrying - handle it in DAL.
Propagating specific exception info to user has hardly any benefit because usually the user cannot do anything about it anyway. So a generic error message usually makes do.
All unexpected and selected expected exceptions need to be logged with as much info as possible. It is also advisable that you get email with the exception info.
Now specifically to NHibernate - if NH throws an exception it is advised that you close and discard the currently active ISession and just fail. Because the session might be in an unknown/inconsistent state and trying to resurrect it can do more harm than good.
Obviously depending on scale and type of your app and number of various systems/programmers/etc. involved you really might to handle the logging yourself.

A recursive way to display Exception Messages in ASP.NET

I have started to make heavy use of exceptions, I'm sure I'll grow out of it as a learn the advantages and disadvantages the hard way, but until I've become an exception guru I'd like to know if this technique is acceptable.
I intend to wrap, say a database exception in my own 'SorryFailedToSaveYourData' exception and then recursively moved through the exception displaying the messages, kinda like this:
Try
DoSomeWork
Catch
BuildErrorMessage(lblError,ex)
End Try
Public Sub BuildErrorMessage(ByVal lbl As Label, ByVal ex As Exception)
lbl.Text += "<br />" & ex.Message
While Not ex.InnerException Is Nothing
BuildErrorMessage(lbl, ex.InnerException)
End While
End Sub
Is this practice useful or I have I completely missed the boat when it comes to handling exceptions? I know you can create your own exceptions but it seems like overkill for the size of the projects we are working on.
Thanks
I wouldn't display each and every inner exception message to the user of your application. I would catch the real exception (ie SqlException) and rethrow it as your own exception (ie throw new YouCantSaveThisTwiceException("This customer ID already exists") ). Then just display that hand typed message to the user on a nice pretty display screen. Send yourself an email / log file / etc with the full-on stack trace.
This serves two purposes:
1) You get to see the real stack trace which makes it easier for you to find and fix the problem.
2) The users do not have to be shown a big scary stack trace. Instead, they read a nice message written by you which reassures them that although there is a problem, they did not "break" the application.
This works well for exceptions which you don't expect a user to be able to fix with different input. For exceptions which validate user input, often you can catch those in the presentation layer and display your nice message back to them on a label without leaving the form.
Only (ONLY!!!) use this technique if you know exactly what you are going to be catching and you give the users clear instruction on how to fix it. Otherwise, you end up with the worst of both worlds. The users don't know what to do, and you are not alerted of the presence of a bug. Never wrap an entire method in a try-catch simply to "catch all" exceptions. That type of handling should be done globally at the application level.
I do all of my global exception handling (emailing, logging, etc) in the application_error handler method within Global.asax. You could also create an HttpModule which handles application errors. Then you can carry that functionality with you from project to project.
ex.ToString() will build the exception text formatted, you should use that rather than the .Message as it might not give you the full information you will need for debugging.
I would also recommend passing a stringbuilder down the recursion instead of a label using AppendLine(), this way you can also use that text to send email notifications, write the event viewer, as well as a log file. For displaying in your UI (it looks like you want html) simply set the labels text value to
StringBuilder.ToString().Replace(Environment.NewLine, "<br />")
You're building a label inside of an exception, presumably because you want to display the message to the user. If your exception spans more than one tier of the application (you mentioned wrapping your own data exception), then this is a terrible idea as it will violate encapsulation and force your exception handling to be using UI elements.
Generally, though, you'll want to not display error messages to the user. What does a user care that a stack overflow happened? He only cares that the application is broken and that an error report was logged and sent to the appropriate team.
Generally you want to have exceptions if and only if the application is in a state in which it can no longer run. If it's something that just happens conditionally you'll want to handle it explicitly with conditions to check for it rather than using the exception mechanism.
For example, if you know users will be connecting from home and you can't guarantee there will be an Internet connection, you check for an Internet connection and display a message saying the user needs to connect, instead of just trying to use an Internet connection and creating an exception if none exists.
Edit
I misread your question at first, you probally don't want to do this if your displaying the information to the end user. You will want to do what I am suggesting if your going to log the exception for you to troubleshoot latter.
====
This is standard although I would also capture the stack trace and any items in the Data property (Although I've not seen any framework code use this you never know and its useful if your going throw your own exceptions or rethrow an exception.
Although your actual code has an error in it your probally end up in an infinite loop since your outer exception will always have an inner exception.
Public Sub BuildErrorMessage(ByVal lbl As Label, ByVal ex As Exception)
lbl.Text += "<br />" & ex.Message
If Not ex.InnerException Is Nothing Then
BuildErrorMessage(lbl, ex.InnerException)
End If
End Sub

A First Chance Exception

've been running through the MSDN help documents to get a hang of Visual Basic. After trying out the example using timers --one drags a label and timer component into the designer and adds the following to the components subroutine
Label1.Text = My.Computer.Clock.LocalTime.ToLongTimeString
The output for the immediate window during debug is the following
A first chance exception of type
'System.InvalidCastException' occured
in Microsoft.VisualBasic.dll
A first
chance exception of type
'System.InvalidCastException' occured
in Microsoft.VisualBasic.dll
The same error occurs on a previous MSDN example using a context menu component. Should I Try...Catch...Finally this error and try to move on? Or, am I dealing with something much more serious?
When you see something about a first chance exception, it only means that an exception was caught within the code you called but does not necessarily mean that the code failed. If the code runs without causing your program to crash and returns a valid value, then do not have a problem. You will also see output in the debug window about first chance exceptions when you implement your own try/catch blocks.
In the Debug menu -> Exceptions, you can enable the debugger to stop when an Exception is first thrown, even if it would be caught later; if you want to find out what's happening, this is the easiest way to do it
In the first chance exception examine the details of the exception. You should see a stack frame/trace property. In there you should see what line the error occurs on. This should help you.
In the IDE try going to Tools > Options > Projects and Solutions > VB Defaults and setting Option Strict to 'On' - this may help catch casting problems when you compile your project rather than when you run it.
A 'first chance execption' does not necessarily mean you have a problem in your code. It could mean the IDE or the compiler or any other involved component encountered and handled an error and in the process the debugger is notified and the exception is being reported to the immediate window. This is an excellent post on the topic:
http://blogs.msdn.com/davidklinems/archive/2005/07/12/438061.aspx
A quick and easy solution for debug and diag of First Chance Exception is :
AppDomain.CurrentDomain.FirstChanceException += CurrentDomainOnFirstChanceException;
and then
private void CurrentDomainOnFirstChanceException(object sender, FirstChanceExceptionEventArgs firstChanceExceptionEventArgs)
{
if (firstChanceExceptionEventArgs.Exception is NullReferenceException)
{
// do your handling and debugging :)
}
}
Multiple First Chance Exception during the runtime can cripple the performance of your application because exception handling is expensive. Especially in web apps. You can add this handler and look at specific first chance exceptions and try to avoid/correct them.