Consider the following code:
using (IRandomAccessStream stream = await storageFile.OpenReadAsync())
{
using (DataReader dataReader = new DataReader(stream))
{
uint length = (uint)stream.Size;
await dataReader.LoadAsync(length);
txtbox.Text = dataReader.ReadString(length);
}
}
storageFile.OpenReadAsync may throw exception, System.IO.FileNotFoundException is one possible exception type. MSDN topic StorageFile.OpenReadAsync http://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.storagefile.openreadasync doesn't contain list of exception types thrown by this method. How can I find this information from documentation? I can catch an Exception type, but this is poor programming practice.
In cases where it is impossible to find all list of exceptions I usually use approach from VS SDK ErrorHandler.IsCriticalException:
try
{
// ...
}
catch(Exception e)
{
if (ErrorHandler.IsCriticalException(e))
{
throw;
}
// log it or show something to user
}
You can decompile the Microsoft.VisualStudio.Shell.11.0.dll to find the list of exceptions, which ErrorHandler defines as Critical:
StackOverflowException
AccessViolationException
AppDomainUnloadedException
BadImageFormatException
DivideByZeroException
In the case of Windows Runtime I think that it will be good also to verify some of the HResult values in Exception, like E_OUTOFMEMORY, E_ABORT, E_FAIL, and maybe something else.
Also I found that BugSense is awesome help for logging exceptions. I use it not only for unhandled exception, but also for situations like this, where I have no idea what this method can throw. It allows to send custom logging (including exceptions) with BugSenseHandler.Instance.LogException, so I just collect information about different kind of exceptions (including exceptions with some unexpected HResult) and make some improvements for my app in each release.
Related
assume we have following peace of code in C#:
try{
....
try{
throw new Exception1("exception1");
}catch(Exception exception){
...
throw new Exception2("exception2");
}
}catch(Exception exception){
...
log(exception.message);
}
is it possible in log point(outer catch) to access exception1 object and log that one as well?
Here are two reasonable examples of what I think you are talking about. They illustrate what I was trying to describe in the comments as well as what #Jonesopolis describes.
First, my case. Say you are writing a utility that calls some lower-level service that may throw. You may want to describe the behavior of the utility in a way that the exceptions that may bubble up have more meaning to the caller. In this case, I've documented that my utility will throw an ApplicationException if there is a problem.
I do this from two places, the first one when I check some pre-conditions (that the path name is neither null or empty and that it is a valid file name (I'm assuming that there is an IsValidFileName function I can call)).
But the other place is that if I try to do the operation and it throws (I haven't checked that File.ReadAllLines actually ever throws an IOException, but I'm guessing it can). In this case, I don't want to burden my users with catching a possible IOException, instead, I translated it into an ApplicationException that I document. I wrap the IOException with a catch and throw of my ApplicationException, but I include the IOException as the inner exception so that debugging and tracking down other issues works. The code looks like:
public IEnumerable<string> AccessFile(string pathName)
{
if (string.IsNullOrEmpty(pathName) || !IsValidFileName(pathName))
{
throw new ApplicationException("Invalid Path Name");
}
try
{
var result = File.ReadAllLines(pathName);
return result;
}
catch (IOException ex)
{
throw new ApplicationException("Error Accessing File", ex);
}
}
It's that second parameter to the ApplicationException that sets up the inner exception. This pattern is very common.
The other example is what #Jonesopolis describes.
Here I have a work function doing something. My application architecture demands that I do logging at the level of whatever the DoSomethingImportant function is at. So, it catches any exceptions that get thrown at a lower level. However, that code wants to bubble up any exceptions to the DoSomethingImportant function's caller. Here, it just uses the throw keyword with no argument. That rethrows the current exception and lets it bubble through.
It's important to use throw; with no arguments, and not throw ex;. The former allows the existing exception to bubble up. The latter unwinds the stack at the catch site, and then throws a new exception, losing all the stack information that might point to the faulting location.
This is the typical code that I'm talking about. It's also a very common pattern:
public void DoSomethingImportant()
{
try
{
DoSomethingLowLevel();
}
catch (Exception ex)
{
GetLogger().Log(ex);
throw;
}
}
I am using a library that doesn't seem to document the exceptions. This library is used to communicate with a product the company makes. I want to be able to differentiate between the exceptions that get thrown but I don't know the names of the exceptions (for example between a communication timeout or under-voltage condition).
All of their examples only use catch(Exception ex). How can can I find what I need to use to catch the individual errors? When I do ex.toString() I get something like this:
System.Exception: Timeout
at CMLCOMLib.EcatObj.Initialize()
at copley_cmo_test.MainWindow.btnConnect_Click(Object sender, RoutedEventArgs e)
in c:\Users\adam.siembida\Desktop\copley_cmo_test\copley_cmo_test\MainWindow.xaml.cs:line 41
This:
System.Exception: Timeout
shows that they're just throwing a bare System.Exception, e.g.
if (weHaveNoApiDesignSkills)
{
throw new Exception("Timeout");
}
It's possible that there are some exceptions which are better designed, but the one you've shown isn't promising :(
Unfortunately unless you start using the message in the exception to differentiate between them (which is almost always a bad idea) you're stuck. It may be worth asking the authors of the library to see if they can improve matters for a future release.
Catch it with a catch-all construct such as catch(Exception ex), then examine the Type returned by ex.GetType(). If it's equal to typeof(Exception), it means that they aren't throwing anything more specific than Exception.
By the way, if you're stopped when the exception has been caught (ie, in a catch block), if you enter $exception in the watch window, you will see the entire exception.
When the API in library which you are using is not documented properly , you should catch the base exception and log it not only by the message instead whole exception by converting the exception to string . Eg.
try
{
//api call which throws exception.
}
catch(Exception ex)
{
//log ex.ToString();
}
use a decompiler for example:
http://www.jetbrains.com/decompiler/
in .net there's no explicit exception declaration like in java so as i see it it's the only way.
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.
Exceptions sometimes occur. When they do, they're logged and later analyzed. The log obviously contains the stack-trace and other global information, but often crucial context is missing. I'd like to annotate an exception with this extra information to facilitate post-mortem debugging.
I don't want to try{...}catch{... throw;} since that counts as catching an exception and that makes debugging harder (during development I'd like the app to stop and the debugger to react when the original exception is thrown, and not when the outermost uncaught exception is). First-chance exception handlers aren't a workaround since there are unfortunately too many false positives.
I'd like to avoid excessive overhead in the normal, non-exceptional case.
Is there any way to store key pieces of context (e.g. filename being processed or whatever) in an exception in a way that doesn't catch the exception?
I am taking a shot at this building off of Adam's suggestion of Aop. my solution would be Unity rather than postsharp and the only question I would have is whether the exception is being caught inside of invoke, which it likely is...
public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
{
//execute
var methodReturn = getNext().Invoke(input, getNext);
//things to do after execution
if (methodReturn.Exception != null)
methodReturn.Exception.Data.Add("filename", "name of file");
return methodReturn;
}
}
There is nothing wrong with the following pattern:
try
{
// Do Something
}
catch (GeneralException ex)
{
throw new SpecificException(
String.Format("More specifics ({0}) in message", someData),
moreContext,
new {even, more, context},
ex);
}
This is precisely the pattern to use, for instance, when the "Do Something" is to, say, open a file of some kind. The "SpecificException" might be "can't read configuration file".
I would not use AOP to catch the exceptions. Instead I would use the interception class to LOG the exception + all arguments to the method that threw the exception. And then let the original exception be thrown again
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
What are some of the most common mistakes you've seen made when handling exceptions?
It seems like exception handling can be one of the hardest things to learn how to do "right" in .Net. Especially considering the currently #1 ranked answer to Common programming mistakes for .NET developers to avoid? is related to exception handling.
Hopefully by listing some of the most common mistakes we can all learn to handle exceptions better.
What are some of the most common mistakes you've seen made when handling exceptions?
I can think of lots.
First read my article on categorization of exceptions into vexing, boneheaded, fatal and exogenous:
http://ericlippert.com/2008/09/10/vexing-exceptions/
Some common errors:
Failure to handle exogenous exceptions.
Failure to handle vexing exceptions.
Construction of methods that throw vexing exceptions.
Handling exceptions that you actually cannot handle, like fatal exceptions.
Handling exceptions that hide bugs in your code; don't handle a boneheaded exception, fix the bug so that it isn't thrown in the first place
Security error: failure to the unsafe mode
try
{
result = CheckPassword();
if (result == BadPassword) throw BadPasswordException();
}
catch(BadPasswordException ex) { ReportError(ex); return; }
catch(Exception ex) { LogException(ex); }
AccessUserData();
See what happened? We failed to the unsafe mode. If CheckPassword threw NetworkDriverIsAllMessedUpException then we caught it, logged it, and accessed the user's data regardless of whether the password was correct. Fail to the safe mode; when you get any exception, assume the worst.
Security error: production of exceptions which leak sensitive information, directly or indirectly.
This isn't exactly about handling exceptions in your code, it's about producing exceptions which are handled by hostile code.
Funny story. Before .NET 1.0 shipped to customers we found a bug where it was possible to call a method that threw the exception "the assembly which called this method does not have permission to determine the name of file C:\foo.txt". Great. Thanks for letting me know. What is stopping said assembly from catching the exception and interrogating its message to get the file name? Nothing. We fixed that before we shipped.
That's a direct problem. An indirect problem would be a problem I implemented in LoadPicture, in VBScript. It gave a different error message depending upon whether the incorrect argument is a directory, a file that isn't a picture, or a file that doesn't exist. Which means you could use it as a very slow disk browser! By trying a whole bunch of different things you could gradually build up a picture of what files and directories were on someone's hard disk. Exceptions should be designed so that if they are handled by untrustworthy code, that code learns none of the user's private information from whatever they did to cause the exception. (LoadPicture now gives much less helpful error messages.)
Security and resource management error: Handlers which do not clean up resources are resource leaks waiting to happen. Resource leaks can be used as denial-of-service attacks by hostile partial trust code which deliberately creates exceptions-producing situations.
Robustness error: Handlers must assume that program state is messed up unless handling a specific exogenous exception. This is particularly true of finally blocks. When you're handling an unexpected exception, it is entirely possible and even likely that something is deeply messed up in your program. You have no idea if any of your subsystems are working, and if they are, whether calling them will make the situation better or worse. Concentrate on logging the error and saving user data if possible and shut down as cleanly as you can. Assume that nothing works right.
Security error: temporary global state mutations that have security impacts need to be undone before any code that might be hostile can run. Hostile code can run before finally blocks run! See my article on this for details:
http://blogs.msdn.com/ericlippert/archive/2004/09/01/224064.aspx
Re-throwing exceptions like this:
try
{
// some code here
}
catch(Exception ex)
{
// logging, etc
throw ex;
}
This kills the stack trace, making is far less usable. The correct way to rethrow would be like this:
try
{
// some code here
}
catch(Exception ex)
{
// logging, etc
throw;
}
Catching all exceptions when in many cases you should attempt to catch specific exceptions:
try {
// Do something.
} catch (Exception exc) {
// Do something.
}
Rather than:
try {
// Do something.
} catch (IOException exc) {
// Do something.
}
Exceptions should be ordered from most specific to least.
Rethrowing an exception with a meaningless message.
try
{
...
}
catch (Exception ex)
{
throw new Exception("An error ocurred when saving database changes").
}
You won't believe how often I see code like this running in production.
Nobody is talking about seeing empty catch blocks like these....
try{
//do something
}
catch(SQLException sqex){
// do nothing
}
Also never use Exception handling for creating alternate method flows...
try{
//do something
}catch(SQLException sqex){
//do something else
}
Not using using on IDisposable objects:
File myFile = File.Open("some file");
callSomeMethodWhichThrowsException(myFile);
myFile.Close();
myFile does not get closed until myFile's finalizer is called (which may be never) because an exception was thrown before myFile.Close() was called.
The proper way to do this is
using(File myFile = File.Open("some file"))
{
callSomeMethodWhichThrowsException(myFile);
}
This gets translated by the compiler into something like:
File myFile = File.Open("some file");
try
{
callSomeMethodWhichThrowsException(myFile);
}
finally
{
if(myFile != null)
myFile.Dispose(); //Dispose() calls Close()
}
So the file gets closed even in the face of exceptions.
Forget to set the inner exception when rethrowing a catched exception
try
{
...
}
catch (IOException ioException)
{
throw new AppSpecificException("It was not possible to save exportation file.")
// instead of
throw new AppSpecificException("It was not possible to save exportation file.", ioException);
}
When I posted this answer, I forget to mention that we should always consider when to include inner exception or not due to security reasons. As Eric Lippert pointed out on another answer for this topic, some exceptions can provide sensitive information about the implementation details of the server. Thus, if the caller who will be handling the exception is not trusted, it is not a good idea to include the inner exception information.
Empty catch:
//What's the point?
catch()
{}
Rethrowing:
//Exceptions are for *adding* detail up the stack
catch (Exception ex)
{throw ex;}
Assuming an exception that covers many scenarios was something specific. A real life scenario was a web app where the exception handling always assumed all errors were session time outs and logged and reported all errors as session time outs.
Another example:
try
{
Insert(data);
}
catch (SqlException e)
{
//oh this is a duplicate row, lets change to update
Update(data);
}
To log Exception.Message instead of Exception.ToString()
Many times, I see code logging only the exception message while it should log the return of ToString method. ToString provides much more information about the exception than the Message. It includes information like inner exception and stack trace besides the message.
Trying to catch OutOfMemoryException or StackOverflowException - those lead to a shutdown of the runtime, hence to way to catch them from within the same Process (or even from the CLR as a whole?)
OutOfMemoryException: The exception that is thrown when there is not enough memory to continue the execution of a program.
"Starting with the .NET Framework version 2.0, a StackOverflowException object cannot be caught by a try-catch block and the corresponding process is terminated by default. Consequently, users are advised to write their code to detect and prevent a stack overflow."
Failing to catch possible exceptions inside a catch handler. This can cause the wrong exception to be propagated upwards.
For example:
try
{
DoImportantWork();
}
catch
{
Cleanup();
throw;
}
What happens if Cleanup() throws an exception? You don't want to see an Exception pointing to the Cleanup() method in this catch handler. You want the original error. You could try to log the cleanup error, but even your logging code needs exception handling to avoid throwing exceptions from it.
try
{
DoImportantWork();
}
catch
{
try
{
Cleanup();
}
catch
{
// We did our best to clean up, and even that failed.
// If you try to log this error, the logging may throw yet another Exception.
}
throw;
}
Wrong
try
{
// Do something stupid
}
catch
{
// ignore the resulting error because I'm lazy, and later spend
// a week trying to figure out why my app is crashing all over
// the place.
}
Better
try
{
/// do something silly.
}
catch (InvalidOperationException ex)
{
/// respond, or log it.
}
catch (Exception e)
{
/// log it.
}
Using exceptions for normal flow control. Exceptions should exceptional. If it's a good / expected operation, use return values, etc.