Catch All Unhandled Exceptions - c#

I'm going to catch all unhandled exceptions in my Winforms app. Here is the shortened code:
[STAThread]
static void Main()
{
if (!AppDomain.CurrentDomain.FriendlyName.EndsWith("vshost.exe"))
{
Application.ThreadException += new ThreadExceptionEventHandler(MyCommonExceptionHandlingMethod);
}
Application.Run(new frmLogin());
}
private static void MyCommonExceptionHandlingMethod(object sender, ThreadExceptionEventArgs t)
{
Exception ex = t.Exception;
StackTrace trace = new StackTrace(ex, true);
var db = new MyDataContext();
Error error = new Error();
error.FormName = trace.GetFrame(0).GetMethod().ReflectedType.FullName;
error.LineNumber = trace.GetFrame(0).GetFileLineNumber();
error.ColumnNumber = trace.GetFrame(0).GetFileColumnNumber();
error.Message = ex.Message;
db.Errors.InsertOnSubmit(error);
db.SubmitChanges();
if (new frmError(ex).ShowDialog() != DialogResult.Yes)
System.Diagnostics.Process.GetCurrentProcess().Kill();
}
The issue is that sometimes FormName, LineNumber and ColumnNumber are not correctly returned. Here is the result that I sometimes get:
--FormName-- --Line/Column-- --Message--
System.Linq.Enumerable 0 0 Sequence contains no matching element
System.RuntimeMethodHandle 0 0 Exception has been thrown by the target of an invocation.
System.Number 0 0 Input string was not in a correct format.
System.Number 0 0 Input string was not in a correct format.
System.ThrowHelper 0 0 Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
As you can see, LineNumbers and ColumnNumbers are 0. FormName is System.Linq.Enumerable ...
How can I solve the problem?

How can I solve the problem?
When no .pdb is present for a given module, the stack trace information will necessarily not be able to include file names, line, or column numbers.
To get them, you need to make sure you have the .NET .pdb available and loaded. There are a number of resources available which describe how to do this. See Cannot step into .NET framework source code, for example, or Advanced .NET Debugging - PDBs and Symbol Stores. You can use your favorite web search engine to find additional resources.
I'll note also that you are describing the type name as the "FormName", which is incorrect. It's only the form name when the exception was in fact thrown by your form. Unhandled exceptions are always bugs, and as such are very often thrown by framework or other library code, and the types won't be forms.
I will also mention that catching all exceptions is useful only for diagnosing bugs. This should not be used as an attempt to improve general reliability of a program (except to the extent that better diagnosis can allow you to fix bugs). When an unhandled exception occurs, you should log it and then kill the process. Allowing a process to continue executing after an unhandled exception occurs is dangerous for your data, and can lead to complacency with respect to bug-fixing.

Related

Application Insights not reporting custom properties and call stack

I'm logging different exceptions with the following method that accepts the exception as well as some context information string.
public void LogException(string notes, Exception e)
{
var properties = new Dictionary<string, string>()
{
{ "notes", notes }
};
telemetry.TrackException(e, properties);
}
The exceptions are reported correctly, but they are missing
The custom property "notes"
The call stack
is the exception actually thrown ? are you catching that exception? if you just do
client.TrackException( new Exception() );
there won't be a stack frames on some OS's / runtimes.
but if you do
try
{
throw new Exception();
}
catch (Exception e)
{
client.TrackException( e );
}
you will get a stack trace. something about the act of throwing the exception actually populates the underlying frame the sdk uses.
for your custom property, that should be showing up right away, although sometime's there's a lag between a new custom property being sent the first time, and when it shows up in metadata as a field to display. Also, you're limited to 200 distinct named custom properties, so if you've already sent 200 other properties, the "notes" field will just get thrown away.
in general for UWP / release / .net native, you should still have frames, they just won't be very readable, they'll be memory addresses, but there's still a stack of them, and if you have the pdb's, etc, you can reverse engineer what was where.
though the above looks like "catastrophic failure" exceptions that might not have stack frames available?

How to know an exact location of NullReferenceException [duplicate]

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 8 years ago.
I am trying to a catch nullreference exception but I want to know the exact location (at which point or line I am getting that exception). I have one class named Employee and it has two properties: _Id and _Name.
static void Main(string[] args)
{
Employee empobj = new Employee();
try
{
empobj = null;
//empobj._Id = empobj._Id.ToString();
Console.WriteLine(empobj._Id);
Console.WriteLine(empobj._Name);
Console.ReadLine();
}
catch (NullReferenceException e)
{
Console.WriteLine("Exception caught: {0}", e.InnerException);
Console.ReadLine();
}
}
In visual studio go to Debug->Exceptions menu.
Then select "Common Language Runtime Exceptions", Check the Thrown checkbox. This will break the execution when exception is thrown. You can find the breaked line is where exceptio is thrown.
In case of NullReferenceException you won't get much help about stacktrace, but this way you can get the cause easily.
Look at the stack trace and it will have a break down of the execution tree, stating line numbers along with function names and so on. You can do this by debugging, outputting your exception stack trace to some medium, or by removing the try/catch and letting the exception halt execution of your application.
The key would be, though, to work around the exception so that it doesn't happen, if it's not an exceptional circumstance (i.e. if you expect that this is a scenario that could very well happen); so if your application can check, such as
if (thing != null) {
var id = thing.Id;
if (id != null) {
var idText = id.ToString();
// and so on
}
} else {
}
Where in the else, you either continue a different route, let the user retry or whatever.
If it is a truly exceptional circumstance (i.e. things should never be null) and the app can't do anything if it is, then let the exception happen, it breaks the application.
Stack trace is the way to go, but the exception is coming from the following lines:
Console.WriteLine(empobj._Id);
Console.WriteLine(empobj._Name);
You are setting the employee object to null
empobj = null;
and then trying to access member variables from that class, which will no longer have values for these variables

Unhandled Exception in C# Console Application causing AppCrash

I have a Windows Console application built in Visual Studio 2010 and it keeps crashing but the error is not caught by the visual studio debugging tool nor by try/catch statements in my code.
I have managed to locate the WER file on my system and would like to be able to understand the contents of the file so I can pinpoint exactally what is causing the unhandled exception.
I would be greatful if anyone can offer some idea on how I can use the following information to locate the process causing me this problem and also what the exception may be...
The information from the WER file is:
Version=1
EventType=APPCRASH
EventTime=129973086237604286
ReportType=2
Consent=1
ReportIdentifier=91331e8b-2dc8-11e2-977b-080027f7e5bb
IntegratorReportIdentifier=91331e8a-2dc8-11e2-977b-080027f7e5bb
WOW64=1
Response.type=4
Sig[0].Name=Application Name
Sig[0].Value=SAGE_TESTING.vshost.exe
Sig[1].Name=Application Version
Sig[1].Value=10.0.30319.1
Sig[2].Name=Application Timestamp
Sig[2].Value=4ba2084b
Sig[3].Name=Fault Module Name
Sig[3].Value=ntdll.dll
Sig[4].Name=Fault Module Version
Sig[4].Value=6.1.7600.16385
Sig[5].Name=Fault Module Timestamp
Sig[5].Value=4a5bdb3b
Sig[6].Name=Exception Code
Sig[6].Value=c015000f
Sig[7].Name=Exception Offset
Sig[7].Value=000845bb
DynamicSig[1].Name=OS Version
DynamicSig[1].Value=6.1.7600.2.0.0.272.7
DynamicSig[2].Name=Locale ID
DynamicSig[2].Value=2057
DynamicSig[22].Name=Additional Information 1
DynamicSig[22].Value=0a9e
DynamicSig[23].Name=Additional Information 2
DynamicSig[23].Value=0a9e372d3b4ad19135b953a78882e789
DynamicSig[24].Name=Additional Information 3
DynamicSig[24].Value=0a9e
DynamicSig[25].Name=Additional Information 4
DynamicSig[25].Value=0a9e372d3b4ad19135b953a78882e789
Here is the section of code I believe to be causing the exception to be thrown:
//Data from the project linked to the split data
if (oSplitData.Project != null)
{
oProject = oSplitData.Project as SageDataObject190.Project;
oBasicDetail.ProjectID = oProject.ProjectID;
oBasicDetail.ProjectReference = oProject.Reference.ToString();
}
else
{
oBasicDetail.ProjectID = -1;
oBasicDetail.ProjectReference = "NO_PROJECT";
}
To add to all the above I seem to have found that there is a general exception that is being thrown but it doesn't help me out much - if anyone can put some light on this it would be great:
Unhandled exception at 0x78bc7361 in SAGE_TESTING.exe: 0xC0000005: Access violation reading location 0xfeeefeee.
If your program is multi-threaded and the exception is thrown in one of the spawned threads, the Exception may not be caught depending on how you do exception handling in your program.
You can add a catch-all exception handler like this:
class Program
{
static void Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler;
// Your code here
}
static void UnhandledExceptionHandler(object sender, UnhandledExceptionEventArgs e)
{
Console.WriteLine(e.ExceptionObject.ToString());
Environment.Exit(1);
}
}
UPDATE
Based on the code you posted, here are some things to look at
Put a try/catch block around the code you posted.
Are you sure that oSplitData is not null?
In the following line, oProject will be null if oSplitData.Project is not of type SageDataObject190.Project. Test for null.
oProject = oSplitData.Project as SageDataObject190.Project;
You are probably dealing with so-called corrupted state exceptions. These exceptions corrupt the process in a way so it is usually more safe to kill the process since it is very difficult to impossible to recover from such an error, even if it would be only for running a short catch-clause. Examples are StackOverflowExceptions, OutOfMemoryExceptions or AccessViolationExceptions.
There is an extensive and generally interesting explanation on corrupted state exceptions in this article.
What is helpful on getting a hand on such exceptions is to use DebugDiag. With this tool from Microsoft (download on this page) you can define a crash rule which generates a crashdump for your failed process. You can easily open these dump files in Visual Studio, where you may find the source of the exception that lead to the failure. This is not guaranteed but it often helped me in the past to nail down some nasty errors.
Are you invoking non-managed C++ or other code?
I'd try something like
static void Main()
{
try
{
DoSomethingUseful() ;
}
catch ( Exception e )
{
// managed exceptions caught here
}
catch
{
// non-managed C++ or other code can throw non-exception objects
// they are caught here.
}
return ;
}
See Will CLR handle both CLS-Complaint and non-CLS complaint exceptions?
Also C++ try, catch and throw statements at msdn: http://msdn.microsoft.com/en-us/library/6dekhbbc(v=vs.100).aspx
And MSIL opcode throw (0x7A) allows the throwing any object reference. C#, however, does not allow it.
But it looks like they improved things with .Net 2.0 and started wrapping oddball stuff in an RuntimeWrappedException.

How to fix "'System.AggregateException' occurred in mscorlib.dll"

I'm receiving an unhandled exception while debugging, and the program stops executing. The debugger doesn't show me the line so I don't know what to fix.
An unhandled exception of type 'System.AggregateException' occurred in mscorlib.dll
Additional information: A Task's exception(s) were not observed either by Waiting on the Task or accessing its Exception property. As a result, the unobserved exception was rethrown by the finalizer thread.
Cannot obtain value of local or argument '<this>' as it is not available at this instruction pointer, possibly because it has been optimized away. System.Threading.Tasks.TaskExceptionHolder
How can I troubleshoot this problem?
I also found this question which is pretty similar.
As the message says, you have a task which threw an unhandled exception.
Turn on Break on All Exceptions (Debug, Exceptions) and rerun the program.
This will show you the original exception when it was thrown in the first place.
(comment appended): In VS2015 (or above). Select Debug > Options > Debugging > General and unselect the "Enable Just My Code" option.
You could handle the exception directly so it would not crash your program (catching the AggregateException). You could also look at the Inner Exception, this will give you a more detailed explanation of what went wrong:
try {
// your code
} catch (AggregateException e) {
}
The accepted answer will work if you can easily reproduce the issue. However, as a matter of best practice, you should be catching any exceptions (and logging) that are executed within a task. Otherwise, your application will crash if anything unexpected occurs within the task.
Task.Factory.StartNew(x=>
throw new Exception("I didn't account for this");
)
However, if we do this, at least the application does not crash.
Task.Factory.StartNew(x=>
try {
throw new Exception("I didn't account for this");
}
catch(Exception ex) {
//Log ex
}
)
In my case I ran on this problem while using Edge.js — all the problem was a JavaScript syntax error inside a C# Edge.js function definition.

Log external but not own assembly first chance exceptions

Catching Own First Chance Exceptions
AppDomain.CurrentDomain.FirstChanceException += FirstChanceException;
private static void FirstChanceException(object sender, System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs e)
{
// I would like to log exceptions happening outside my assembly?
// But this event does not receive external FirstChanceExceptions
// (unlike Visual Studio debug output)
myLogger.Log(e.Exception);
}
Example
I would like to log A first chance exception of type 'System.IO.IOException' occurred in WindowsBase.dll
But not log A first chance exception of type 'System.DivideByZeroException' occurred in MyApp.exe
Solution?
Is there a way to get notified of those exceptions arising in dlls such as mscorlib.dll?
Note the interest is to log in the production release, not only in debugging.
Why
Exceptions that occur in external dll dependencies can cause trouble, even if they are handled there.
For example, due to an exception a null value may be returned from an external method (instead of returning the desired output of x) and even though my code mostly handles such abnormal output it is useful to know what exactly went wrong and where - because while I may be able to avoid fatal exceptions then more often than not that null value makes part of my app non-functional. So logging the external first chance exception would provide valuable information to help rectify the issue / turn that null into x. And this may be present in only given environments / for specific users etc...
You can use StackTrace class to check what is the source of the exception:
var stackTrace = new StackTrace(e.Exception);
var sourceFrame = stackTrace.GetFrame(0);
var throwingMethod = sourceFrame.GetMethod();
var sourceAssembly = throwingMethod.DeclaringType.Assembly;
var assemblyName = sourceAssembly.GetName().Name;
bool isMyApp = assemblyName == "MyApp";

Categories

Resources