Identify exception origin from exception properties in WPF (C# .Net) app - c#

I am recently assigned a task to extend an existing WPF (C# .Net) application for an error handler. The handler is supposed to display a friendly message with possible easy solution for the user. It is required that I change nearly no code = I can only work in App.xaml.cs code behind. My approach is to try to identify the error from the stack trace and from the properties of the innermost exception. So far, I am using these three identifiers:
string identifierMethod= new System.Diagnostics.StackTrace(ex.GetBaseException()).GetFrame(0).GetMethod().Name;
string identifierObject = ex.GetBaseException().TargetSite.ReflectedType.FullName;
string identifierHResult = ex.GetBaseException().HResult.ToString();
//ex is the uppermost exception coming to App
I need to identify the root method and object where the exception originated. Combining these three seems to work for me but I don’t think it is very clean and robust and I fear there could be some exception that will have duplicate combination of these three identifiers. Sometimes the innermost exception’s stack trace is null, sometimes it seems to me the identifiers do not really describe the lowermost method or object constructor which caused the Exception.
I know I could ideally use Exception Data or Source properties assigning some identifiers in try catch block where the Exception originate but I simply cannot. I know similar question were asked but they only gave me what I have now.
Thanks a lot for any suggestions and ideas.

You can use Checked Exceptions to announce the caller methods about the callees' exceptions. And in caller methods, you can easily handle the exception by their types, identify the exception origin, and have a friendly message.
To add the Checked Exception feature into the C#, you can use this nugget package: Portia.Roslyn.CheckedException.

Related

Appropriate Exception to throw if you've manually detected a threading error

Suppose I write some multi-threaded C# code. (I know ... bad idea from the get-go ;) )
I have some code B, which I expect to only get called after code A has completed. I write and review my code carefully to convince myself that this is true, but I can't actually enforce that expectation, I can only check whether it is true.
So I put the checks in, and if the check ever fails, I want to throw and exception so that the developer gets a big shouty log message saying "Nope, ya fucked up; there's still an edge case where the threading doesn't do what you'd convinced yourself it did."
What's the best C# Exception type to throw here?
My instinct is to go with that old stand-by InvalidOperationException or possibly just a raw new Exception(message). But it would be nice if there were a slightly more specific type I could throw (like throwing an ArgumentException when that's the issue that's happened)
There are a few Exception types that auto-complete from Thread or Sync but they all look like they're intended for much deeper problems. i.e. there's something wrong with the actual threads. Here the thread are all fine ... it's the developer's threading logic that's in error.
Are there any sensible pre-existing Exception classes to use here?
An InvalidOperationException is the most suitable built in exception for this situation.
See it's official documentation remarks section:
InvalidOperationException is used in cases when the failure to invoke a method is caused by reasons other than invalid arguments. Typically, it is thrown when the state of an object cannot support the method call.
(emphasis mine).
Of course, there's nothing stopping you from creating your own Exception class if you want something more specific, but that would only make sense if you want the exception to carry information that doesn't fit inside the InvalidOperationException (and of course, if you do choose to create your own exception class, be sure to follow the guidlines in How to create user-defined exceptions:
Derive from an existing Exception class
use the word Exception as a suffix to the class name (MyVeryOwnSpecialException)
Implement at least three public constructors:
3.a: A constructor with no parameters
3.b: A constructor that takes in a string message
3.c: A constructor that takes in a string message and an Exception inner exception.

WCF Stripping detail from System.SecurityException

I am implementing IErrorHandler for a WCF service, with the intention of automatically logging the messages.
During testing I decided to throw a System.SecurityException with an inner exception and some user defined data:
try
{
LevelTwo();
}
catch (Exception innerEx)
{
var outerEx = new SecurityException("Is security special?", innerEx);
outerEx.Data.Add("foo", "bar");
throw outerEx;
}
Yet when it hits my ProvideFault method in my error handler it has already been converted to a System.ServiceModel.FaultException with a Message of "Access is denied". The original message, exception type, data and inner exception have all been lost, and I cannot log them. Other exception types work as expected, exposing all those properties for logging.
I presume that there is a framework implementation of IErrorHandler that is hit first, and converts it, stripping the detail and providing a generic message, which is all well and good generally, but not when I want to log the details.
Somebody has posted the same issue on MSDN but didn't get any particularly good answers.
Ideally I would like to change the order of the error handlers so that mine is hit first - is this possible?
If not - is it possible to remove the existing handler, and if so, are there any undesirable consequences?
EDIT
Following Christian's advice below it appears that the exception is getting caught by the code in SyncMethodInvoker.Invoke()
catch (System.Security.SecurityException e)
{
DiagnosticUtility.TraceHandledException(e, TraceEventType.Warning);
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError
(AuthorizationBehavior.CreateAccessDeniedFaultException());
}
I think this means that Security Exceptions are a very special case, and that there probably isn't a good way around this, but I would appreciate any suggestions.
I'm not a proper computer right now, so I cannot test it myself, but I think WCF indeed converts any SecurityException into what you observe.
If you look at the complete call stack of your "rethrown" SecurityExceptions, you should see stack frames hinting at the location where they originate. With that information you can look into http://sourceof.net/ to look at the relevant code.
Having that said, there are multiple implementations of IOperationInvoker in WCF that handle the different calling styles (async, sync, etc.) of service operations.
For an example see:
http://referencesource.microsoft.com/#System.ServiceModel/System/ServiceModel/Dispatcher/SyncMethodInvoker.cs,181
http://referencesource.microsoft.com/#System.ServiceModel/System/ServiceModel/Dispatcher/AsyncMethodInvoker.cs,140
So, I think the order of IErrorHandlers is nothing that helps with this issue, as the exception gets converted/stripped/replaced before error handlers are even called.
I would consider creating my own fault type for security issues, like a SecurityFault type and then throwing that as FaultException<SecurityFault>(...). That fault type could have all the properties you want. Additionally, since the fault type is a DataContract and the properties are DataMembers, you don't risk getting serialization issues, because you may inadvertently put non-serializable data into the exception's Data.

Is there an easy way to identify where an exception was thrown from the Exception object?

So, if I recall correctly, I seem to remember seeing that there were some new annotations added to C# in 4.5 that allow you to pinpoint exactly where an exception was thrown (class, method, line) via a logger or something. But prior to that, is there any built-in way to at least identify the class and method from which the exception was thrown from the actual exception object without having to parse the stack trace? I'd like to be able to use exception object to say, output a message to a log that says something like "Exception was thrown at MyProject.MyClass.MyMethod(int, string). Message: <exception message>
I realize there are some 3rd party libraries out there that can help with this, but I'd rather keep it simpler if possible while learning a bit more about the FCL. The intent isn't to change what an exception is, but rather to make them more useful in unhandled situations. For instance, an unhandled exception is thrown and caught by a filter. The filter logs the exception and rethrows it. It would be nice if the log that is created can state "It was thrown over here, see the full stack trace for more info." That would make it quicker for us to view the where without having to swim through the stack trace which, in some cases (at least for some of our older stuff) can be very misleading, resulting in chasing our tails only to discover that we would have found the problem quickly if we new exactly where to start.
Use System.Diagnostics.StackTrace if you really need to parse out the individual frames from an Exception object:
using System;
using System.Diagnostics;
public class Program
{
public static void Main(string[] args)
{
try
{
Thrower();
}
catch (Exception e)
{
var trace = new StackTrace(e);
Console.WriteLine(trace.GetFrame(0).GetMethod());
}
}
private static string Thrower()
{
throw new Exception("Boom");
}
}
The feature you are referring to is called Caller Info Attributes and doesn't really have anything to do with exceptions, per se. It is general feature designed mostly for troublshooting. The information is inserted into the assembly at compile time when you use it, similar to __LINE__, __FILE__, __FUNCTION__ macros in C++.
For the source of exception you may look on Exception.Source property, which provides an information like:
The name of the application or the object that causes the error.
You don't need to parse stack trace, it's just a string with all data, which may become usefull in certain cases. Remember that exception ocures in exceptional cases and you need as much information as it can be get.

Creating exception classes for lot different error codes

I am writing a custom .Net SDK for the mapping program MapInfo Pro, mapinfo only exposes two methods to use over COM void Do(string cmd) and string Eval(string cmd). When you use one of these methods and you do something invaild, it returns a a COMException with a error message and I get the error code from MapInfo. So for example an error message looks like this:
418 "Table not found."
Now I would like to throw some kind of meaning full exception rather then just a exception with a number and message that people have to catch then use a if block to check what error, something they say they only want to catch and do something meaning full with. Something like TableNotFoundException.
The biggest problem is there are currently 1999 possible error messages, now I don't want a exception class for everyone of those errors.
The idea of the SDK is that people use my objects and methods rather then Do and Eval(they can stil use them if they want).
Should I,
everywhere in my SDK that I call Do and Eval use a try catch and then check the error code and throw something more meaning full from there, because I know what errors I should get.
or
I have somekind of God lookup list in the Do and Eval that when a COMException is thrown it lookups the error code and throws the meaningfull error from there? Meaning I don't have to wrap every call to Do and Eval in try catch blocks(there are a lot of calls)
Bit of a tricky thing to explain so I hope people can understand it.
Thanks.
Wrap the calls to Do and Eval in your own function which catches MapInfo errors.
As there are so many error types, you could create an enum with some more descriptive names or a dictionary mapping error numbers to more friendly names (if the original ones aren't good enough) - you don't want 1999 exception classes, so I'd suggest using only one exception class that contains the error number and description. You're saying that users could use Do and Eval directly, so they should know how to handle these error numbers, anyway.
Alternatively, you could create a few hierarchical exception types and decide which one to throw (needs something a dictionary mapping 0-1999 => matching exception type) - that way, users can be a bit more specific about which types of errors to catch.
As per AndiDog, creating a few exception classes that group the couple of thousand errors into some reasonable types. You should probably still pass the original error number out, just in case.
While you're doing that, read this article to sort out how those groups might be assembled, and maybe which ones you DON'T want to catch.

Best practices for exception management in Java or C# [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I'm stuck deciding how to handle exceptions in my application.
Much if my issues with exceptions comes from 1) accessing data via a remote service or 2) deserializing a JSON object. Unfortunately I can't guarantee success for either of these tasks (cut network connection, malformed JSON object that is out of my control).
As a result, if I do encounter an exception I simply catch it within the function and return FALSE to the caller. My logic is that all the caller really cares about is if the task was successful, not why it is wasn't successful.
Here's some sample code (in JAVA) of a typical method)
public boolean doSomething(Object p_somthingToDoOn)
{
boolean result = false;
try{
// if dirty object then clean
doactualStuffOnObject(p_jsonObject);
//assume success (no exception thrown)
result = true;
}
catch(Exception Ex)
{
//don't care about exceptions
Ex.printStackTrace();
}
return result;
}
I think this approach is fine, but I'm really curious to know what the best practices are for managing exceptions (should I really bubble an exception all the way up a call stack?).
In summary of key questions:
Is it okay to just catch exceptions but not bubble them up or formally notifying the system (either via a log or a notification to the user)?
What best practices are there for exceptions that don't result in everything requiring a try/catch block?
Follow Up/Edit
Thanks for all the feedback, found some excellent sources on exception management online:
Best Practices for Exception Handling | O'Reilly Media
Exception Handling Best Practices in .NET
Best Practices: Exception Management (Article now points to archive.org copy)
Exception-Handling Antipatterns
It seems that exception management is one of those things that vary based on context. But most importantly, one should be consistent in how they manage exceptions within a system.
Additionally watch out for code-rot via excessive try/catches or not giving a exception its respect (an exception is warning the system, what else needs to be warned?).
Also, this is a pretty choice comment from m3rLinEz.
I tend to agree with Anders Hejlsberg and you that the most callers only
care if operation is successful or not.
From this comment it brings up some questions to think about when dealing with exceptions:
What is the point this exception being thrown?
How does it make sense to handle it?
Does the caller really care about the exception or do they just care if the call was successful?
Is forcing a caller to manage a potential exception graceful?
Are you being respectful to the idoms of the language?
Do you really need to return a success flag like boolean? Returning boolean (or an int) is more of a C mindset than a Java (in Java you would just handle the exception) one.
Follow the error management constructs associated with the language :) !
It seems odd to me that you want to catch exceptions and turn them into error codes. Why do you think the caller would prefer error codes over exceptions when the latter is the default in both Java and C#?
As for your questions:
You should only catch exceptions that you can actually handle. Just
catching exceptions is not the right thing to do in most cases.
There are a few exceptions (e.g. logging and marshalling exceptions
between threads) but even for those cases you should generally
rethrow the exceptions.
You should definitely not have a lot of try/catch statements in your
code. Again, the idea is to only catch exceptions you can handle.
You may include a topmost exception handler to turn any unhandled
exceptions into something somewhat useful for the end user but
otherwise you should not try to catch each and every exception in
every possible place.
This depends on the application and the situation. If your building a library component, you should bubble up exceptions, although they should be wrapped to be contextual with your component. For example if your building an Xml Database and let's say you are using the file system to store your data, and you are using file system permissions to secure the data. You wouldn't want to bubble up a FileIOAccessDenied exception as that leaks your implementation. Instead you would wrap the exception and throw an AccessDenied error. This is especially true if you distribute the component to third parties.
As for if it's okay to swallow exceptions. That depends on your system. If your application can handle the failure cases and there is no benefit from notifying the user why it failed then go ahead, although I highly recommend that your log the failure. I've always found it frustating being called to help troubleshoot an issue and find they were swallowing the exception (or replacing it and throwing a new one instead without setting the inner exception).
In general I use the following rules:
In my components & libraries I only catch an exception if I intend to handle it or do something based on it. Or if I want to provide additional contextual information in an exception.
I use a general try catch at the application entry point, or the highest level possible. If an exception gets here I just log it and let it fail. Ideally exceptions should never get here.
I find the following code to be a smell:
try
{
//do something
}
catch(Exception)
{
throw;
}
Code like this serves no point and should not be included.
I would like to recommend another good source on the topic. It's an interview with inventors of C# and Java, Anders Hejlsberg and James Gosling respectively, on the topic of Java's Checked Exception.
Failure and Exceptions
There are also great resources at the bottom of the page.
I tend to agree with Anders Hejlsberg and you that the most callers only care if operation is successful or not.
Bill Venners: You mentioned
scalability and versioning concerns
with respect to checked exceptions.
Could you clarify what you mean by
those two issues?
Anders Hejlsberg: Let's start with
versioning, because the issues are
pretty easy to see there. Let's say I
create a method foo that declares it
throws exceptions A, B, and C. In
version two of foo, I want to add a
bunch of features, and now foo might
throw exception D. It is a breaking
change for me to add D to the throws
clause of that method, because
existing caller of that method will
almost certainly not handle that
exception.
Adding a new exception to a throws
clause in a new version breaks client
code. It's like adding a method to an
interface. After you publish an
interface, it is for all practical
purposes immutable, because any
implementation of it might have the
methods that you want to add in the
next version. So you've got to create
a new interface instead. Similarly
with exceptions, you would either have
to create a whole new method called
foo2 that throws more exceptions, or
you would have to catch exception D in
the new foo, and transform the D into
an A, B, or C.
Bill Venners: But aren't you breaking
their code in that case anyway, even
in a language without checked
exceptions? If the new version of foo
is going to throw a new exception that
clients should think about handling,
isn't their code broken just by the
fact that they didn't expect that
exception when they wrote the code?
Anders Hejlsberg: No, because in a lot
of cases, people don't care. They're
not going to handle any of these
exceptions. There's a bottom level
exception handler around their message
loop. That handler is just going to
bring up a dialog that says what went
wrong and continue. The programmers
protect their code by writing try
finally's everywhere, so they'll back
out correctly if an exception occurs,
but they're not actually interested in
handling the exceptions.
The throws clause, at least the way
it's implemented in Java, doesn't
necessarily force you to handle the
exceptions, but if you don't handle
them, it forces you to acknowledge
precisely which exceptions might pass
through. It requires you to either
catch declared exceptions or put them
in your own throws clause. To work
around this requirement, people do
ridiculous things. For example, they
decorate every method with, "throws
Exception." That just completely
defeats the feature, and you just made
the programmer write more gobbledy
gunk. That doesn't help anybody.
EDIT: Added more details on the converstaion
Checked exceptions are a controversial issue in general, and in Java in particular (later on I'll try to find some examples for those in favor and opposed to them).
As rules of thumb, exception handling should be something around these guidelines, in no particular order:
For the sake of maintainability, always log exceptions so that when you start seeing bugs, the log will assist in pointing you to the place your bug has likely started. Never leave printStackTrace() or the likes of it, chances are one of your users will get one of those stack traces eventually, and have exactly zero knowledge as to what to do with it.
Catch exceptions you can handle, and only those, and handle them, don't just throw them up the stack.
Always catch a specific exception class, and generally you should never catch type Exception, you are very likely to swallow otherwise important exceptions.
Never (ever) catch Errors!!, meaning: Never catch Throwables as Errors are subclasses of the latter. Errors are problems you will most likely never be able to handle (e.g. OutOfMemory, or other JVM issues)
Regarding your specific case, make sure that any client calling your method will receive the proper return value. If something fails, a boolean-returning method might return false, but make sure the places you call that method are able to handle that.
You should only catch the exceptions you can deal with. For example, if you're dealing with reading over a network and the connection times out and you get an exception you can try again. However if you're reading over a network and get a IndexOutOfBounds exception, you really can't handle that because you don't (well, in this case you wont) know what caused it. If you're going to return false or -1 or null, make sure it's for specific exceptions. I don't want a library I'm using returning a false on a network read when the exception thrown is the heap is out of memory.
Exceptions are errors that are not part of normal program execution. Depending on what your program does and its uses (i.e. a word processor vs. a heart monitor) you will want to do different things when you encounter an exception. I have worked with code that uses exceptions as part of normal execution and it is definitely a code smell.
Ex.
try
{
sendMessage();
if(message == success)
{
doStuff();
}
else if(message == failed)
{
throw;
}
}
catch(Exception)
{
logAndRecover();
}
This code makes me barf. IMO you should not recover from exceptions unless its a critical program. If your throwing exceptions then bad things are happening.
All of the above seems reasonable, and often your workplace may have a policy. At our place we have defined to types of Exception: SystemException (unchecked) and ApplicationException (checked).
We have agreed that SystemExceptions are unlikely to be recoverable and will bve handled once at the top. To provide further context, our SystemExceptions are exteneded to indicate where they occurred, e.g. RepositoryException, ServiceEception, etc.
ApplicationExceptions could have business meaning like InsufficientFundsException and should be handled by client code.
Witohut a concrete example, it's difficult to comment on your implementation, but I would never use return codes, they're a maintenance issue. You might swallow an Exception, but you need to decide why, and always log the event and stacktrace. Lastly, as your method has no other processing it's fairly redundant (except for encapsulation?), so doactualStuffOnObject(p_jsonObject); could return a boolean!
After some thought and looking at your code it seems to me that you are simply rethrowing the exception as a boolean. You could just let the method pass this exception through (you don't even have to catch it) and deal with it in the caller, since that's the place where it matters. If the exception will cause the caller to retry this function, the caller should be the one catching the exception.
It can at times happen that the exception you are encountering will not make sense to the caller (i.e. it's a network exception), in which case you should wrap it in a domain specific exception.
If on the other hand, the exception signals an unrecoverable error in your program (i.e. the eventual result of this exception will be program termination) I personally like to make that explicit by catching it and throwing a runtime exception.
If you are going to use the code pattern in your example, call it TryDoSomething, and catch only specific exceptions.
Also consider using an Exception Filter when logging exceptions for diagnostic purposes. VB has language support for Exception filters. The link to Greggm's blog has an implementation that can be used from C#. Exception filters have better properties for debuggability over catch and rethrow. Specifically you can log the problem in the filter and let the exception continue to propagate. That method allows an attaching a JIT (Just in Time) debugger to have the full original stack. A rethrow cuts the stack off at the point it was rethrown.
The cases where TryXXXX makes sense are when you are wrapping a third party function that throws in cases that are not truly exceptional, or are simple difficult to test without calling the function. An example would be something like:
// throws NumberNotHexidecimalException
int ParseHexidecimal(string numberToParse);
bool TryParseHexidecimal(string numberToParse, out int parsedInt)
{
try
{
parsedInt = ParseHexidecimal(numberToParse);
return true;
}
catch(NumberNotHexidecimalException ex)
{
parsedInt = 0;
return false;
}
catch(Exception ex)
{
// Implement the error policy for unexpected exceptions:
// log a callstack, assert if a debugger is attached etc.
LogRetailAssert(ex);
// rethrow the exception
// The downside is that a JIT debugger will have the next
// line as the place that threw the exception, rather than
// the original location further down the stack.
throw;
// A better practice is to use an exception filter here.
// see the link to Exception Filter Inject above
// http://code.msdn.microsoft.com/ExceptionFilterInjct
}
}
Whether you use a pattern like TryXXX or not is more of a style question. The question of catching all exceptions and swallowing them is not a style issue. Make sure unexpected exceptions are allowed to propagate!
I suggest taking your cues from the standard library for the language you're using. I can't speak for C#, but let's look at Java.
For example java.lang.reflect.Array has a static set method:
static void set(Object array, int index, Object value);
The C way would be
static int set(Object array, int index, Object value);
... with the return value being a success indicator. But you're not in C world any more.
Once you embrace exceptions, you should find that it makes your code simpler and clearer, by moving your error handling code away from your core logic. Aim to have lots of statements in a single try block.
As others have noted - you should be as specific as possible in the kind of exception you catch.
If you're going to catch an Exception and return false, it should be a very specific exception. You're not doing that, you're catching all of them and returning false. If I get a MyCarIsOnFireException I want to know about it right away! The rest of the Exceptions I might not care about. So you should have a stack of Exception handlers that say "whoa whoa something is wrong here" for some exceptions (rethrow, or catch and rethrow a new exception that explains better what happened) and just return false for others.
If this is a product that you'll be launching you should be logging those exceptions somewhere, it will help you tune things up in the future.
Edit: As to the question of wrapping everything in a try/catch, I think the answer is yes. Exceptions should be so rare in your code that the code in the catch block executes so rarely that it doesn't hit performance at all. An exception should be a state where your state machine broke and doesn't know what to do. At least rethrow an exception that explains what was happening at the time and has the caught exception inside of it. "Exception in method doSomeStuff()" isn't very helpful for anyone who has to figure out why it broke while you're on vacation (or at a new job).
My strategy:
If the original function returned void I change it to return bool. If exception/error occurred return false, if everything was fine return true.
If the function should return something then when exception/error occurred return null, otherwise the returnable item.
Instead of bool a string could be returned containing the description of the error.
In every case before returning anything log the error.
Some excellent answers here. I would like to add, that if you do end up with something like you posted, at least print more than the stack trace. Say what you were doing at the time, and Ex.getMessage(), to give the developer a fighting chance.
try/catch blocks form a second set of logic embedded over the first (main) set, as such they are a great way to pound out unreadable, hard to debug spaghetti code.
Still, used reasonably they work wonders in readability, but you should just follow two simple rules:
use them (sparingly) at the low-level to catch library handling issues, and stream them back into the main logical flow. Most of the error handling we want, should be coming from the code itself, as part of the data itself. Why make special conditions, if the returning data isn't special?
use one big handler at the higher-level to manage any or all of the weird conditions arising in the code that aren't caught at a low-level. Do something useful with the errors (logs, restarts, recoveries, etc).
Other than these two types of error handling, all of the rest of the code in the middle should be free and clear of try/catch code and error objects. That way, it works simply and as expected no matter where you use it, or what you do with it.
Paul.
I may be a little late with the answer but error handling is something that we can always change and evolve along time. If you want to read something more about this subject I wrote a post in my new blog about it. http://taoofdevelopment.wordpress.com
Happy coding.

Categories

Resources