I have a C# (.net 4.0) program, whose main is calling methods from an external FTP library - a dll the project references. The logic is in a try-catch block, and the catch prints the error. The exception handler has a generic parameter: catch(Exception ex). The IDE is VS.
Sometimes the FTP library throws the following division by zero exception. The problem is it is not caught in the catch block, and the program crashes.
Exceptions originated in my wrapper code are caught. Anyone has any idea what the difference is and how the exception can be caught?
The exception:
Description: The process was terminated due to an unhandled exception.
Exception Info: System.DivideByZeroException
Stack:
at ComponentPro.IO.FileSystem+c_OU.c_F2B()
at System.Threading.ExecutionContext.runTryCode(System.Object)
at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode, CleanupCode, System.Object)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
at System.Threading.ThreadHelper.ThreadStart()
There is a similar problem described here and also here for explanation. As said in one of the comments an FTP server should always handle protocol violations itself without crashing. You should pick another FTP if you can. However, if you want to keep using that DLL you need to handle the exception at App Domain level as Blorgbeard pointed out.
Here an example of how catch the exception using the AppDomain.UnhandledException event:
using System;
using System.Security.Permissions;
public class Test
{
[SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlAppDomain)]
public static void Example()
{
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(MyHandler);
try
{
throw new Exception("1");
}
catch (Exception e)
{
Console.WriteLine("Catch clause caught : " + e.Message);
}
throw new Exception("2");
// Output:
// Catch clause caught : 1
// MyHandler caught : 2
}
static void MyHandler(object sender, UnhandledExceptionEventArgs args)
{
Exception e = (Exception)args.ExceptionObject;
Console.WriteLine("MyHandler caught : " + e.Message);
}
public static void Main()
{
Example();
}
}
Related
Say we're using Socket.BeginReceive and passing in a callback method:
var state = new StateObject() { workSocket = socket };
var ret = socket.BeginReceive(state.buffer, 0, StateObject.BufferSize, SocketFlags.None, new AsyncCallback(BeginReceiveCallback), state);
...
private void BeginReceiveCallback(IAsyncResult ar)
{
StateObject state = (StateObject) ar.AsyncState;
int bytes = state.workSocket.EndReceive(ar); //workSocket is the Socket receiving
...
}
If an exception is encountered in the callback and not handled there - where will it go? How/can I catch it?
Doing a bit of reading, I believe this is the answer
The Exceptions get thrown when you call EndReceive. The Begin.../End... pair of methods work like this:
Begin gets called, and returns immediately
The callback gets started in a separate Thread by the runtime
Inside the callback, the actual work gets done blocking the Thread. This work is done by invoking the End... method
So, the End... method is actually doing the work. So, if an exception gets thrown, you can catch it there.
Here is some code demonstrating this with comments. If you want to just try it out here is a Dotnetfiddle with this code edited to work on Dotnetfiddle:
using System;
using System.Threading;
using System.Threading.Tasks;
namespace BeginEndInvokeTest
{
public class Program
{
public static async Task Main(string[] args)
{
// This is just here for setup
var caller = new AsyncDemo.AsyncMethodCaller(AsyncDemo.Test);
// This is your 'socket.BeginReceive' call
var ar = caller.BeginInvoke(3000, AsyncCallback, caller);
// Wait so the program doesn't exit prematurely
await Task.Delay(5000);
}
static void AsyncCallback(IAsyncResult ar)
{
var caller = (AsyncDemo.AsyncMethodCaller) ar.AsyncState;
try
{
// If our exception wouldn't be thrown here (which is impossible),
// the program would print "No exception was thrown"
caller.EndInvoke(ar);
Console.WriteLine("No exception was thrown");
}
catch (Exception)
{
Console.WriteLine("Exception encountered");
}
}
}
public class AsyncDemo
{
public static string Test(int callDuration)
{
// Simply write something to the console, simulate work
// and throw an exception
Console.WriteLine("Test method begins");
Thread.Sleep(callDuration);
throw new Exception("Testing");
}
public delegate string AsyncMethodCaller(int callDuration);
}
}
So in short, you can only catch the Exceptions at the End... call, nowhere else.
Edit to address where does the exception go when it isn't caught.
Honestly, I have no idea where it goes. Further testing and trial n' error gave me nothing. It seems like the whole runtime just crashes. When I didn't catch the exception I get a console out with a stack trace that shows where the exception was thrown (inside the Test method, as expected), alongside something I've never seen before: Unhandled Exception: System.Exception: Testing.
There is also a second stack trace saying :
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.EndInvokeHelper(Message reqMsg, Boolean bProxyCase)
at System.Runtime.Remoting.Proxies.RemotingProxy.Invoke(Object NotUsed, MessageData& msgData)
...
So, yeah, it seems like the runtime crashes when you don't catch it.
Source: I cobbled this answer together using this Microsoft API documentation. Some further info can be found here as Calling synchronous methods asynchronously.
I have a C# program which runs a system tray application - transferring / moving / creating / editing files in the background.
There is alot of exception handling and loop handling to prevent the program from crashing / getting stuck if the user manual deletes a file the program is working with.
Unfortunately one of the computer the program is running on is having the program crash. The computer is very hard to get, and cannot have debugging software loaded on (it is an embedded PC outside with no network access).
I have tried finding the cause of the crash (such as an unhandled exeption) however have not found anything and do not have access to the PC as it is in a remote location.
I was hoping to find a way to use AppDomain / an UnhandledExceptionEventHandler to catch all unhandled exceptions and log them for diagnosis.
However the exception I have (deliberately) created in the office inside the class "DoSomething.class", are crashing the WinForm application rather than logging the exception error.
My code is:
//Current domain for the unhandled exception handling
AppDomain currentDomain;
[SecurityPermission(SecurityAction.Demand, Flags=SecurityPermissionFlag.ControlAppDomain)]
public MainForm()
{
InitializeComponent();
currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionHandler);
CreateTimer.Interval = Settings.Default.CreateTimer;
CreateTimer.Start();
RunCopyProtocol();
ChangeFilesTimer.Interval = 10000;
ChangeFilesTimer.Start();
RunChangeFiles();
throw new Exception("ABC");
}
public void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs args)
{
try
{
Exception ex = (Exception)args.ExceptionObject;
SetLabel(ex);
}
finally { }
}
private string SetLabel(Exception ex)
{
String str;
str = ex.Message;
Label1.Text = str;
return str;
}
private void ChangeFilesTimer_Tick(object sender, EventArgs e)
{
RunChangeFiles();
throw new Exception("2");
}
Why doesn't the throw new exception call the unhandled exception error?
How would I use AppDomain to get the unhandled exception handler to handle this exception / exceptions in the RunChangeFiles?
Code on AppDomain is based of MSDN examples
If your timer is a System.Timers.Timer the reason is documented by MSDN here:
The Timer component catches and suppresses all exceptions thrown by event handlers for the Elapsed event.
Take a look at this similar question:
How do I get the Exception that happens in Timer Elapsed event?
You'll have to catch the exceptions that are thrown in the elapsed handler, and rethrow them on a ThreadPool thread.
Using your code above and extending the answer from the referenced question:
private void ChangeFilesTimer_Tick(object sender, EventArgs e)
{
try
{
RunChangeFiles();
}
catch (Exception ex)
{
ThreadPool.QueueUserWorkItem(
_ => { throw new Exception("Exception on timer thread.", ex); });
}
}
If your timer is a System.Windows.Forms.Timer then you will need to hook into the Application.ThreadException event to handle unhandled exceptions.
Subscribe to this event prior to calling Application.Run().
You can also handle logging of the Exception in a local exception handling block before rethrowing the exception.
try
{
/// ...
}
catch (Exception ex)
{
if (ex is ArgumentException)
{
/// handle known or specific exceptions here
}
else
{
/// log then rethrow unhandled exceptions here
logExceptions(ex);
throw;
}
}
I have following error handler in my console application
Main Procedure:
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(ErrorHandler);
Handler Procedure:
static void ErrorHandler(object sender, UnhandledExceptionEventArgs args)
{
Exception e = (Exception)args.ExceptionObject;
... Loging Error ...
//Environment.Exit(?);
}
And the problem is that error is logged but after that application failed and windows popup (application is not responding) is showed.
So i want to add Environment.Exit() to prevent that behavior, but how to specify the exitCode from the exception ? I dont want to set Exit(0) (which means everything is okay) because i also want see the error (only information that some error happened, exception is already logged) in the scheduler application which trigger this script.
Thank you
Most programmers simply use Environment.Exit(1). Almost always works just fine. But that is not technically correct, if a program dies on an exception then its exit code is normally the same as the underlying exception error code. The event handler ought not change that behavior.
Doing it right is a mouthful:
Environment.Exit(System.Runtime.InteropServices.Marshal.GetHRForException(e));
There's a FUD factor here, you can't completely trust a library with custom exception objects that don't set an error code. Still okay, the fallback is E_FAIL.
Can you use the Exception.HResult?
Consider the following code:
class Program
{
static int Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; ;
if (args.Any() && args[0] == "/t")
{
Console.WriteLine("I am going to throw an exception");
throw new ApplicationException("This is an exception");
}
else
{
Console.WriteLine("I am going to exit");
//Environment.Exit(0);
return 0;
}
}
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Console.WriteLine("An unexpected error has occurred");
Exception ex = (Exception)e.ExceptionObject;
Environment.Exit(ex.HResult);
}
}
Then execute this from a batch file twice - once with the /t parameter and the other without:
#echo off
cls
echo Running Console Application with no error
ConsoleApplication2.exe
echo %errorlevel%
echo Running Console Application with error
ConsoleApplication2.exe /t
echo %errorlevel%
pause
In the first run you exit with 0. I've made Main return an int and just return 0 for successful execution - you can do Environment.Exit(0) here.
With the second run that throws an ApplicationException, the UnhandledException is handled, then Environment.Exit(ex.HResult) is called.
I think the HResult is tied in to specific exceptions as per MSDN. However, you may want different exit codes depending on what caused the exception. In this case you can throw custom exceptions then have some cafuffled logic in the UnhandledException handler:
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Console.WriteLine("An unexpected error has occurred");
Exception ex = (Exception)e.ExceptionObject;
if (ex is MyException)
{
Environment.Exit(10009); // my own exit codes
}
Environment.Exit(ex.HResult);
}
}
class MyException : Exception
{
}
But would you really care why it failed in the console? If you get an unhandled exception then it failed. You can have lots of possible failure points. What are you really going to do with the error code? You have logged the exception out. That provides the vital information.
I have a multithreaded c# project. I have removed a lock, that locked unnecessarily shared objects, and tried to make those shared objects to be for single thread.
The thing is now the process is crashing, with no error whats so ever - not in the event viewer or when I run in debug.
Can anyone suggest a way for me to diagnose the error? Because the fact that visual studio just lets the process stop with nothing for me to work with makes me stuck. My last resort is WinDbg, and I would like to avoid that.
you could try to hook into unhandled app domain exceptions -
http://msdn.microsoft.com/en-GB/library/system.appdomain.unhandledexception.aspx
and also check out unhandled thread exceptions:
https://msdn.microsoft.com/en-GB/library/system.windows.forms.application.threadexception.aspx
(code from example in appdomain link)
using System;
using System.Security.Permissions;
public class Example
{
[SecurityPermission(SecurityAction.Demand, Flags=SecurityPermissionFlag.ControlAppDomain)]
public static void Main()
{
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(MyHandler);
try {
throw new Exception("1");
} catch (Exception e) {
Console.WriteLine("Catch clause caught : {0} \n", e.Message);
}
throw new Exception("2");
}
static void MyHandler(object sender, UnhandledExceptionEventArgs args)
{
Exception e = (Exception) args.ExceptionObject;
Console.WriteLine("MyHandler caught : " + e.Message);
Console.WriteLine("Runtime terminating: {0}", args.IsTerminating);
}
}
// The example displays the following output:
// Catch clause caught : 1
//
// MyHandler caught : 2
// Runtime terminating: True
//
// Unhandled Exception: System.Exception: 2
// at Example.Main()
It's also a good idea to check the Exceptions that cause a Debugger-break in Visual studio.
You can find this unter Debug->Exceptions... or with Crtl+D, E
Maybe visual studio just skips the exception that is causing your crash
I havent written a windows service before and thought everything was going well until I deployed it to live. In dev it works fine and the polling it great, but as soon as it goes into production it falls on its backside after its first loop.
The exception I recieve is:
Application: ProgramName.WinService.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.Exception
Stack:
at ProgramName.WinService.UpdateChecker.StartChecks()
at ProgramName.WinService.UpdateChecker.StartPolling()
at System.Threading.ThreadHelper.ThreadStart_Context(System.Object)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
at System.Threading.ThreadHelper.ThreadStart()
and here is the code that is doing the looping:
private readonly Thread pollingThread;
public UpdateChecker()
{
pollingThread = new Thread(StartPolling);
InitializeComponent();
}
protected override void OnStart(string[] args)
{
pollingThread.Start();
}
protected override void OnStop()
{
pollingThread.Abort();
}
protected void StartPolling()
{
do
{
StartChecks();
//10 seconds
Thread.Sleep(10000);
} while (true);
}
Does anyone have any idea why this would fall over after it runs the first time? am I doing something stupid?
This is the method causing the issue:
public static string GetXmlFromFeed(string strUrl)
{
var rssReq = WebRequest.Create(strUrl);
var rep = rssReq.GetResponse();
return new StreamReader(rep.GetResponseStream()).ReadToEnd();
}
On the GetResponse()
possible a time out and nothing to do with the threading at all then
Looking at the exception stack trace it seems that the StartChecks throws an exception which is not handled and it propagates to the calling thread (this behavior was introduced in .NET 2.0 as before exceptions thrown in child threads weren't propagated).
Try putting a try/catch around it in order to handle this exception.