| Start | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Creating Custom Exceptions You are allowed to implement custom exceptions that can be thrown just like any other exception. This makes sense when you want to make your exceptions distinguishable from other errors during runtime. In this example we will create a custom exception for clear handling of problems the application may have while parsing a complex input. Creating Custom Exception ClassTo create a custom exception create a sub-class of Custom exception become very useful when you want to provide additional information to the catcher: Now, when you Custom classes can implement the following features to support additional scenarios. re-throwingDuring the parsing process, the original exception is still of interest. In this example it is a serializationIn some cases your exceptions may have to cross AppDomain boundaries. This is the case if your parser is running in its own AppDomain to support hot reloading of new parser configurations. In Visual Studio, you can use Using the ParserExceptionYou may also use custom exceptions for catching and wrapping exceptions. This way many different errors can be converted into a single error type that is more useful to the application: When handling exceptions by raising your own custom exceptions, you should generally include a reference the original exception in the Security ConcernsIf exposing the reason for the exception might compromise security by allowing users to see the inner workings of your application it can be a bad idea to wrap the inner exception. This might apply if you are creating a class library that will be used by others. Here is how you could raise a custom exception without wrapping the inner exception: ConclusionWhen raising a custom exception (either with wrapping or with an unwrapped new exception), you should raise an exception that is meaningful to the caller. For instance, a user of a class library may not know much about how that library does its internal work. The exceptions that are thrown by the dependencies of the class library are not meaningful. Rather, the user wants an exception that is relevant to how the class library is using those dependencies in an erroneous way. |
||||||||||||||
Finally block The A try block must be followed by either a In the file-reading we could have used a Even if there is a
|
||||||||||||||
Best Practices Cheatsheet
DO NOT manage business logic with exceptions.Flow control should NOT be done by exceptions. Use conditional statements instead. If a control can be done with Consider the following snippet by Mr. Bad Practices: When execution reaches Since previous snippet only covers logic of exception, what should I do if How about Mr. Best Practices? How would he handle this? Mr. Best Practices achieved same logic with fewer code and a clear & understandable logic. DO NOT re-throw ExceptionsRe-throwing exceptions is expensive. It negatively impact performance. For code that routinely fails, you can use design patterns to minimize performance issues. This topic (opens new window) describes two design patterns that are useful when exceptions might significantly impact performance. DO NOT absorb exceptions with no loggingNever swallow exceptions. Ignoring exceptions will save that moment but will create a chaos for maintainability later. When logging exceptions, you should always log the exception instance so that the complete stack trace is logged and not the exception message only. Do not catch exceptions that you cannot handleMany resources, such as this one (opens new window), strongly urge you to consider why you are catching an exception in the place that you are catching it. You should only catch an exception if you can handle it at that location. If you can do something there to help mitigate the problem, such as trying an alternative algorithm, connecting to a backup database, trying another filename, waiting 30 seconds and trying again, or notifying an administrator, you can catch the error and do that. If there is nothing that you can plausibly and reasonably do, just "let it go" and let the exception be handled at a higher level. If the exception is sufficiently catastrophic and there is no reasonable option other than for the entire program to crash because of the severity of the problem, then let it crash. |
||||||||||||||
Exception Anti-patterns Swallowing ExceptionsOne should always re-throw exception in the following way: Re-throwing an exception like below will obfuscate the original exception and will lose the original stack trace. One should never do this! The stack trace prior to the catch and rethrow will be lost. Baseball Exception HandlingOne should not use exceptions as a substitute for normal flow control constructs (opens new window) like if-then statements and while loops. This anti-pattern is sometimes called Baseball Exception Handling (opens new window). Here is an example of the anti-pattern: Here is a better way to do it: catch (Exception)There are almost no (some say none!) reasons to catch the generic exception type in your code. You should catch only the exception types you expect to happen, because you hide bugs in your code otherwise. Better do: If any other exception happens, we purposedly let the application crash, so it directly steps in the debugger and we can fix the problem. We mustn't ship a program where any other exceptions than these happen anyway, so it's not a problem to have a crash. The following is a bad example, too, because it uses exceptions to work around a programming error. That's not what they're designed for. |
||||||||||||||
Basic Exception Handling Note that handling all exceptions with the same code is often not the best approach. |
||||||||||||||
Handling specific exception types Be careful that exceptions are evaluated in order and inheritance is applied. So you need to start with the most specific ones and end with their ancestor. At any given point, only one catch block will get executed. |
||||||||||||||
| Aggregate exceptions / multiple exceptions from one method Who says you cannot throw multiple exceptions in one method. If you are not used to playing around with AggregateExceptions you may be tempted to create your own data-structure to represent many things going wrong. There are of course were another data-structure that is not an exception would be more ideal such as the results of a validation. Even if you do play with AggregateExceptions you may be on the receiving side and always handling them not realizing they can be of use to you. It is quite plausible to have a method execute and even though it will be a failure as a whole you will want to highlight multiple things that went wrong in the exceptions that are thrown. As an example this behavior can be seen with how Parallel methods work were a task broken into multiple threads and any number of them could throw exceptions and this needs to be reported. Here is a silly example of how you could benefit from this: |
||||||||||||||
| Throwing an exception Your code can, and often should, throw an exception when something unusual has happened. |
||||||||||||||
| Unhandled and Thread Exception AppDomain.UnhandledException This event provides notification of uncaught exceptions.It allows the application to log information about the exception before the system default handler reports the exception to the user and terminates the application.If sufficient information about the state of the application is available, other actions may be undertaken — such as saving program data for later recovery.Caution is advised, because program data can become corrupted when exceptions are not handled. Application.ThreadException This event allows your Windows Forms application to handle otherwise unhandled exceptions that occur in Windows Forms threads. Attach your event handlers to the ThreadException event to deal with these exceptions, which will leave your application in an unknown state. Where possible, exceptions should be handled by a structured exception handling block. And finally exception handling |
||||||||||||||
| Using the exception object You are allowed to create and throw exceptions in your own code. Instantiating an exception is done the same way that any other C# object. You can then use the Note: If you're throwing a new exception inside a catch block, ensure that the original exception is passed as "inner exception", e.g. In this case it is assumed that the exception cannot be handled but some useful information is added to the message (and the original exception can still be accessed via It will show something like: System.DivideByZeroException: Cannot divide by b because it is zero ---> System.DivideByZeroException: Attempted to divide by zero. If you're trying this example in LinqPad, you'll notice that the line numbers aren't very meaningful (they don't always help you). But passing a helpful error text as suggested above oftentimes significantly reduces the time to track down the location of the error, which is in this example clearly the line c = a / b; in function |
||||||||||||||
| Implementing IErrorHandler for WCF Services Implementing IErrorHandler for WCF services is a great way to centralize error handling and logging. The implementation shown here should catch any unhandled exception that is thrown as a result of a call to one of your WCF services. Also shown in this example is how to return a custom object, and how to return JSON rather than the default XML. Implement IErrorHandler: In this example we attach the handler to the service behavior. You could also attach this to IEndpointBehavior, IContractBehavior, or IOperationBehavior in a similar way. Attach to Service Behaviors: Configs in Web.config: Here are a few links that may be helpful on this topic: Other Examples: IErrorHandler doesn't seem to be handling my errors in WCF .. any ideas? (opens new window) How to make custom WCF error handler return JSON response with non-OK http code? (opens new window) How do you set the Content-Type header for an HttpClient request? (opens new window) |
||||||||||||||
| Nesting of Exceptions & try catch blocks. One is able to nest one exception / This way one can manage small blocks of code which are capable of working without disrupting your whole mechanism. Note: Avoid Swallowing Exceptions (opens new window) when throwing to the parent catch block |
Read Article
https://develop.horje.com/learn/1434/reference