Link to home
Start Free TrialLog in
Avatar of Noty661
Noty661Flag for United States of America

asked on

How should I deal with Unhandled Exceptions in a form from a class library?

I'm working on an MDI application that loads "Modules" for users to work with.

It is simply a front end to the user forms which are part of various class libraries that it loads during startup.

I'm loading the DLLs at runtime using System.Reflection.Assembly.LoadFile, then setting a Form variable to equal the form within the DLL and adding it to the MDI window.

The problem is that I'm not quite sure how to go about catching unhandled errors that happen in the class library itself. If there's an error in one of the child windows from the class library the entire application crashes.

Ideally, all of the DLLs would handle their own errors, but obviously I'd like to handle any "unknowns" in the main front end just in case.

Recap - I'm creating an instance of a form from a class library using Assembly.LoadFile, and displaying it in an MDI window. If the form encounters an error within itself it brings down the entire application.

Below is a simple example of how I am loading the form.

Any assistance would be greatly appreciated!
Dim Assembly As System.Reflection.Assembly = _
System.Reflection.Assembly.LoadFile(ModulePathAndFileName)
 
 
//(All libraries have a frmModule so the front end knows what to load.)"
 
Dim MDIChild As Form = _
Assembly.CreateInstance(ModuleFileNameWithoutPath & ".frmModule")
 
MDIChild.MdiParent = Me
MDIChild.Show

Open in new window

Avatar of ozoid
ozoid
Flag of United Kingdom of Great Britain and Northern Ireland image

Hi
You need to Load your forms/modules each within a separate AppDomain - this will isolate each one and will not cause others to crash one one of them dies.
Something like this :

Imports System.Reflection
...
Dim aDomain as AppDomain  = AppDomain.CreateDomain("Form1Domain")
aDomain.Load(ModulePathAndFileName)


Avatar of Noty661

ASKER

Hi

Thanks for the response.

Using a separate AppDomain crossed my mind earlier, but I don't think I can get that to work because the MDI window would then be in a different AppDomain than what I'm trying to add as it's children.

Is there a way to get around this?
Hi
Yes that is true - but you can do cross domain communication - either by remoting or using other methods :
http://www.codeproject.com/KB/dotnet/XDMessaging.aspx
This may seem a lot more work but will be the only true way to separate your forms and allow them to crash without bringing down the whole application.

Have you configured your exception handling in your compilation (visual studio Debug menu - exceptions) - you should be able to handle and catch all exceptions in theory..

ASKER CERTIFIED SOLUTION
Avatar of Arthur_Wood
Arthur_Wood
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Noty661

ASKER

Ozoid -

Thanks for the link. I read the article, but I'm not sure I understand how that is going to help me add a Form located in another AppDomain to an MDI Window in the current AppDomain. It looks like that is more for sending messages between AppDomains.  Am I missing something?

Hi Arthur -

The MDI Child form that is displayed is non-modal. The program would just continue on at that point since no error occurs when setting the MdiParent or Showing the form.

Any other ideas?




then you need to add similar exception handling (Try...Catch..End Try blocks) in the MDIChild form code.
Avatar of Noty661

ASKER

Thanks for the suggestions.

Try/Catch blocks in the MDIChild form code would work, definitely, but my goal is to handle any MDIChild forms that may be missing an error handler somewhere along the line. It could be possible, and I'd rather the application handle it gracefully. I have a test DLL written specifically to throw an exception. My goal is to make the application (hopefully) handle the exception that occurs in the form from that DLL while it is a Child of the current application's MDI window.

Avatar of Noty661

ASKER

Here's what I've done to get around the problem:

I added an invisible form as the start up form, and THAT form is now calling the main form and showing it as a dialog. If an error occurs in one of the child forms from one of the DLLs that are loaded, it still causes the main form to crash but because it was being shown as a dialog from another form, the other form is able to handle the error and restart the form.

This works in the development environment.

But when compiled, it still just crashes with an "Unhandled exception" error. I'm at a total loss to explain this. Why would handling the error that way work when running it in the development environment and not when running a compiled executable that should be doing the same thing?

Any ideas?
Hi
If you are using Visual Studio - you can configure how the exceptions are handled when in Design mode and on final compilation
have a look through there - you should be able to adjust these and you may be able to catch the exception you are missing
Sorry - the place to look is in the Debug Menu - Exceptions
Avatar of Noty661

ASKER

Hi ozoid

I'm quite positive I'm not missing the exception, I know exactly when and where it occurs because one of the Child forms is a test form designed to crash. (There's a big ol' "CRASH" button :> )

The exception is handled now using what I mentioned above.. but is still acting unhandled in the compiled executable.

So, when I click "CRASH" in the development environment, my error handler handles the error and continues on happily.

When I click "CRASH" in the compiled executable, it tells me it's not handled. :> Same stack trace.




Have you tried the following ..
http://www.devcity.net/Articles/60/1/unhandled_exceptions.aspx

manually adding a handler to catch the un-handled exceptions ?


Avatar of Noty661

ASKER

Yes!

Actually - Now that I think about it, the same problem was happening with that error handler as well. While running in the development environment it dealt with the unhandled exception, but when compiled it did not.

I never thought much about it because the idea to run the main form from  a "starter" form came to me, and I did that.. and it was handling the error just fine until I compiled and ran it. :>

Then i would bite the bullet and go for putting the forms in their own appDomains - at least you can control the crashes and carry on without causing your main form to die.

Are you able to attach the Debugger to the running executable and see the error happen at the point you expect ? - Tools Menu - Attach to Process
Avatar of Noty661

ASKER

Well, honestly, I've never used the debugger. I did attach it to the process, and it looks as though it is "debugging" something .. :> However, when the program crashes the debugger doesn't tell me anything about it. I do know the error is happening at the point I expect though because the stack trace is the same as it is when it crashes in the dev. environment. Only difference is that my error handler works when I'm running it in the IDE vs running the compiled program.

I'm going to try a different approach. Thanks everyone for your help. If anyone thinks of something different please do let me know.

Not quite sure what to do with this question on EE.
Avatar of Noty661

ASKER

I'm going to accept this as a partial solution because the suggestion about error handling led me to use error handling when showing the MDI parent instead of the MDI children (Because the children are non-modal and the Try/Catch block wouldn't have any effect). I created a class to show the parent, rather than keeping it as the startup form.