I am coding a DLL in C++/CLI that is called in a C# based GUI application. I throw a custom exception (derived from Exception class), which, if not swallowed in my DLL, is handled in the final catch block in the GUI code. It works well for all throws, save one:
Im my DLL I have implemented a handler that will listen to SerialPort::DataReceived events. If I get an incorrect packet, I raise a custom exception, which is rethrown in the outermosst try-catch block. The GUI is supposed to display this custom exception. But for some reason an exception raised in this block is not re-thrown. Instead I get an "Unhandled exception" message in Debug mode. When I run the exe directly by double clicking the exe (in release folder) it simply crashes. Apparently, exceptions raised in this event handler method are not handled by the GUI. Or maybe they are not passed to the GUI from my DLL. It doesnt create a problem for other parts of my dll. The only reason I can think for this different behaviour is that the event handler doesn't have a caller. Is my guess correct? or is there some other reason. Any clues on how I can handle this problem? I dont want my application to crash. I just want to raise an exception so that the message can be displayed to the user in the GUI and the application can stop communicating with the serial port.
You need to switch to the UI thread before throwing from that event handler. This is typically accomplished with System::Threading::SynchronizationContext, but if you're using WinForms you can alternatively use System::Windows::Forms::Control::BeginInvoke or System::Windows::Forms::Control::Invoke.
Related
Need help with some VB.net coding (NOT C or c++)
So far I'm using this code to catch errors for specific line(s) of codes:
Try
bla bla bla
Catch ex As Exception
msbox("Error: " & ex.message)
End Try
But sometimes the application stops due to an error where I don't have a catch; how do I on occasions like this call upon a specific Sub (catch the error) for ANY OTHER error in the ENTIRE application where the Sub will display the error message (where I also plan on sending my self an e-mail in that sub to notify me application has stopped)?
I'm not sure if it will conflict with all current Try/Catch commands in my application, but I would prefer to only catch the error on code that currently is not within a Catch handler.
Thank you so much!
This functionality is built into the VB application framework, which is enabled by default in WinForms applications. Open the Application page of the project properties, click the View Application Events button and add a handler for the UnhandledException event using the navigation bar at the top of the code window. Done!
The VB application framework hides some of the complexity of applications that you must implement yourself in C#. It includes a Startup event that you can handle instead of adding code to a Main method, a StartupNextInstance event to support single-instance apps with commandline arguments, multi-threaded splash screen functionality and more.
Regarding your emailing idea, just sure to add in a privacy notice before auto-emailing yourself anything in your apps; this can be a big bone of contention to users, & if an astute one catches it silently phoning home your rep is down the drain.
As for a global error handler, have a look here:
https://www.dotnetcurry.com/patterns-practices/1364/error-handling-dotnet-projects
I am in support team of one legacy VB6 project that involves socket communication.
We got one issue in error handling.
Following are the components of this application.
Main process
Activex Exe process
Main process creates the activex class objects and invokes functions and consumes events (like socket connected,reading etc ) from those objects.
Main process form module have error handlers in all functions.
Main process error handler does following:
Log error in file
Show Msgbox (vbcritical style) to user
In ActiveX exe class,all functions have error handlers
ActiveX process error handler does following
Log error in file
Raise error using Err.raise
We observed when a function of ActiveX class invoked from main process and some error occurs in ActiveX exe function, a runtime error message is displayed from activex exe and ActiveX process terminated even though
error handlers are there in Main process functions.
Is there something wrong in error handlers design or error handlers in one process cannot catch the errors raised in other process?
Is there a simple way to catch all exceptions in your VB.NET applications? I'm interested in making it so that instead of my users seeing a runtime error, they just are told that an error occurred and to contact tech support, then the relevant error information is logged so our support team can look at it afterwards.
You can use the OnUnhandledException application event to catch (almost) every exception that wasn't handled by the code.
On the Project Properties window (double-click project file on the solution explorer or Project Menu -> [Project name] properties), the Application page has a "View Application Events" button that creates a new file in your project.
In that file there are some events that are fired at application level; one of those is the UnhandledException. Whatever you put there will be executed instead of the classic JIT dialog. The UnhandledExceptionEventArgs object has an Exception property with the unhandled exception object, and a ExitApplication property that decides if the application should exit or continue executing.
Namespace My
' The following events are available for MyApplication:
'
' Startup: Raised when the application starts, before the startup form is created.
' Shutdown: Raised after all application forms are closed. This event is not raised if the application terminates abnormally.
' UnhandledException: Raised if the application encounters an unhandled exception.
' StartupNextInstance: Raised when launching a single-instance application and the application is already active.
' NetworkAvailabilityChanged: Raised when the network connection is connected or disconnected.
Partial Friend Class MyApplication
Private Sub MyApplication_UnhandledException(sender As Object, e As Microsoft.VisualBasic.ApplicationServices.UnhandledExceptionEventArgs) Handles Me.UnhandledException
MessageBox.Show(e.Exception.ToString) '<-- the exception object
e.ExitApplication = True '<-- True if you want the application to close; false to continue - if it can
End Sub
End Class
End Namespace
Note that there are still some "über-exceptions" that can't be caught even with this method (out of memory for example), but this way you can log what exceptions are not being correctly handled on your code, or what scenarios are actualy happening that weren't considered at the beggining.
More info here
As a side note: don't rely too much on this event. This has to be for extremely exceptional cases, as what is caught here should be treated ASAP in the corresponding class/module/method. This is a helpful tool for debugging and test cases but having too much exceptions being handled by this event would be a sign of something wrong in your code.
It depends on what environment your application is running in. If you are using WPF or WinForms, you would launch your application using a main method instead of directly launching a form or page. Your main method should then wrap the calls to instantiate the UI in a try catch block.
So, for a WinForms Application, you could do something like this:
Sub Main
Try
Dim MainUI As New Form1
MainUI.Show()
Application.Run
Catch ex As Exception
'Do that fancy exception processing
End Try
End Sub
You can do something similar with WPF. But, WPF also supports an event model where you are notified of exceptions, very similar to the one that ASP.Net uses.
You will never be able to catch the StackOverflowException.
All the others for sure yes. I'm not familiar with VB, but it is easy to achieve in C#. For VB, I think the generic exeption handler could be
Try
...
Catch e As Exception
...
End Try
Of course this has to wrap all your code. You can find more for examples here.
If you have forms application, it is not practical to have the handler around Application.Run() as the only event handler. Keep it there, but add also two others:
When inside the form, and exception occurs, you want to keep execution in that context – keep the form open etc. For this purpose, use ThreadExceptionEventHandler.
And also, for case when application is irrepairably crashing on some problem, add handler to Dispatcher.UnhandledException event. It is last thing executed before the application ends. You can log the exception to disk for later investigation etc. Very useful.
Let's see some good resource how they are applied.
I'm using VB 2010 Express and sometimes my code is just ignored, without any error notification. For example, I have this code at the end of the sub that handles me.Load:
counter = counter is a test line. mPlayer is an object from Toub's sound midi dll, defined like this:
Dim mPlayer As MyMediaPlayer.MyWinPlayer
mPlayer = New MyMediaPlayer.MyWinPlayer()
When the filename contains a valid midi file, it all works and the msgbox's are displayed. When the midi file is NOT valid, I would like an error to be generated or AudioLength to be NULL or some weird value. Instead, no error is triggered and the debugger just exits the sub.
More in detail: the debugger stops at the first breakpoint. Then, when I click 'Continue', the form is displayed, without the debugger ever reaching the other breakpoints or ever producing the MsgBox's.
Could you please explain how to make VB give me the error?
I'm not familiar with the library you are using but any exception due to an invalid file will originate from the MyWinPlayer.Open() method (function in vb-speak). So if an exception is thrown, you need to handle that exception inside of a try-catch. If your current sub does not handle the exception, then the exception will bubble up to the calling method and keep going until there is some place that the exception is handled.
A try-catch block would be something like this (I don't write a lot in vb.net anymore, the syntax may not be perfect):
Try
mPlayer.Open(filename);
Catch ex As Exception
'Do something with the exception
' (e.g. write a log, set a value, or display error message)
End Try
Despite what I have written in the code block above, I would encourage you not to catch a general Exception, and instead focus on the specific type of exception that could be thrown from the Open() method. The reason is you only want to handle exceptions that you know how to handle in the current method and let the other exceptions bubble up. You would need to look at the documentation for the library and see what type of exceptions could be throw and include them.
Another important thing to mention is unless you have a very good reason, do not use an empty catch block (I can't think of one at the moment, but I'm sure there are some very rare uses). An empty catch will just swallow the exception and not do anything with it. It won't even notify you that there was an exception.
Now if you don't handle any exception, the exception should bubble up all the way to the top of the call stack and the debugger should show an Unhandled Exception message and stop there. If it is not doing that then either you are swallowing the exception further down the call stack or you are running into the bug that is mentioned in the possible duplicate Hans Passant mentioned in his comment
MSDN has a pretty decent summary of exception handling in the .NET languages. I would encourage you to read more on the subject.
I get an application error thrown when I close the program using as cancel button which all it does is close the form.
The error says:
"Application appName.exe encountered a serious error and must shut down"
How do I start fixing it? It is not a thrown exception; no other info is given.
What could it be and how do I fix it?
Here is what it was. My application has two forms - login and main form where all the action happens. The login form has two buttons (Login and Cancel). Login button logs user in, closes the login form and opens the main form. Cancel button just closes the login form. To close the form I simply used this.Close().
What was happening though is that I still needed to dispose of the login form explicitly by doing something like:
frmLogin.Dispose();
frmLogin = null;
before exiting the program (in my Program.cs)
So this solved it. I had to make sure that this was being done in both cases: when the user logs in as well as when they choose to not log in.
Crucial fact is that frmLogin is modal, hence Dispose() is not called automatically when closed.
This is typically caused by a system-level exception in your process space that managed code is unable to catch. Typically it happens when you P/Invoke out to native code and give it a bad pointer/parameter and it causes a native exception that is uncaught by the CLR.
Throw a try/catch block around the Application.Run(...) line in your Program.cs, like this:
try
{
Application.Run(new Form1());
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
The message you're seeing means there's a thrown exception that isn't being caught.
Look at some GUI components, DLLs or port resources. Some time is unclosed port, some time some GUI component (i deal with some List GUI component)
I had resharper installed and its cache was creating issue. I deleted the cache and it worked.