Why Re-throw Exceptions? - language-agnostic

I've seen the following code many times:
try
{
... // some code
}
catch (Exception ex)
{
... // Do something
throw new CustomException(ex);
// or
// throw;
// or
// throw ex;
}
Can you please explain the purpose of re-throwing an exception? Is it following a pattern/best practice in exception handling? (I've read somewhere that it's called "Caller Inform" pattern?)

Rethrowing the same exception is useful if you want to, say, log the exception, but not handle it.
Throwing a new exception that wraps the caught exception is good for abstraction. e.g., your library uses a third-party library that throws an exception that the clients of your library shouldn't know about. In that case, you wrap it into an exception type more native to your library, and throw that instead.

Actually there is a difference between
throw new CustomException(ex);
and
throw;
The second will preserve the stack information.
But sometimes you want to make the Exception more "friendly" to your application domain, instead of letting the DatabaseException reach your GUI, you'll raise your custom exception which contains the original exception.
For instance:
try
{
}
catch (SqlException ex)
{
switch (ex.Number) {
case 17:
case 4060:
case 18456:
throw new InvalidDatabaseConnectionException("The database does not exists or cannot be reached using the supplied connection settings.", ex);
case 547:
throw new CouldNotDeleteException("There is a another object still using this object, therefore it cannot be deleted.", ex);
default:
throw new UnexpectedDatabaseErrorException("There was an unexpected error from the database.", ex);
}
}

Sometimes you want to hide the implementation details of a method or improve
the level of abstraction of a problem so that it’s more meaningful to the caller
of a method. To do this, you can intercept the original exception and substitute
a custom exception that’s better suited for explaining the problem.
Take for example a method that loads the requested user’s details from a text file. The method assumes that a text file exists named with the user’s ID and a suffix of “.data”. When that file doesn’t actually exist, it doesn’t make much sense to throw a FileNotFoundException because the fact that each user’s details are stored in a text file is an implementation detail internal to the method. So this method could instead wrap the original exception in a custom exception with an explanatory message.
Unlike the code you're shown, best practice is that the original exception should be kept by loading it as the InnerException property of your new exception. This means that a developer can still analyze the underlying problem if necessary.
When you're creating a custom exception, here's a useful checklist:
• Find a good name that conveys why the exception was thrown and make sure that the name ends with the word “Exception”.
• Ensure that you implement the three standard exception constructors.
• Ensure that you mark your exception with the Serializable attribute.
• Ensure that you implement the deserialization constructor.
• Add any custom exception properties that might help developers to understand and handle your exception better.
• If you add any custom properties, make sure that you implement and override GetObjectData to serialize your custom properties.
• If you add any custom properties, override the Message property so that you can add your properties to the standard exception message.
• Remember to attach the original exception using the InnerException property of your custom exception.

You typically catch and re-throw for one of two reasons, depending on where the code sits architecturally within an application.
At the core of an application you typically catch and re-throw to translate an exception into something more meaningful. For example if you're writing a data access layer and using custom error codes with SQL Server, you might translate SqlException into things like ObjectNotFoundException. This is useful because (a) it makes it easier for callers to handle specific types of exception, and (b) because it prevents implementation details of that layer such as the fact you're using SQL Server for persistence leaking into other layers, which allows you to change things in the future more easily.
At boundaries of applications it's common to catch and re-throw without translating an exception so that you can log details of it, aiding in debugging and diagnosing live issues. Ideally you want to publish error somewhere that the operations team can easily monitor (e.g. the event log) as well as somewhere that gives context around where the exception happened in the control flow for developers (typically tracing).

I can think of the following reasons:
Keeping the set of thrown exception types fixed, as part of the API, so that the callers only have to worry about the fixed set of exceptions. In Java, you are practically forced to do that, because of the checked exceptions mechanism.
Adding some context information to the exception. For example, instead of letting the bare "record not found" pass through from the DB, you might want to catch it and add "... while processing order no XXX, looking for product YYY".
Doing some cleanup - closing files, rolling back transactions, freeing some handles.

Generally the "Do Something" either involves better explaining the exception (For instance, wrapping it in another exception), or tracing information through a certain source.
Another possibility is if the exception type is not enough information to know if an exception needs to be caught, in which case catching it an examining it will provide more information.
This is not to say that method is used for purely good reasons, many times it is used when a developer thinks tracing information may be needed at some future point, in which case you get try {} catch {throw;} style, which is not helpful at all.

I think it depends on what you are trying to do with the exception.
One good reason would be to log the error first in the catch, and then throw it up to the UI to generate a friendly error message with the option to see a more "advanced/detailed" view of the error, which contains the original error.
Another approach is a "retry" approach, e.g., an error count is kept, and after a certain amount of retries that's the only time the error is sent up the stack (this is sometimes done for database access for database calls that timeout, or in accessing web services over slow networks).
There will be a bunch of other reasons to do it though.

FYI, this is a related question about each type of re-throw:
Performance Considerations for throwing Exceptions
My question focuses on "Why" we re-throw exceptions and its usage in application exception handling strategy.

Until I started using the EntLib ExceptionBlock, I was using them to log errors before throwing them. Kind of nasty when you think I could have handled them at that point, but at the time it was better to have them fail nastily in UAT (after logging them) rather than cover a flow-on bug.

The application will most probably be catching those re-thrown exceptions higher up the call stack and so re-throwing them allows that higher up handler to intercept and process them as appropriate. It is quite common for application to have a top-level exception handler that logs or reports the expections.
Another alternative is that the coder was lazy and instead of catching just the set of exceptions they want to handle they have caught everything and then re-thrown only the ones they cannot actually handle.

As Rafal mentioned, sometimes this is done to convert a checked exception to an unchecked exception, or to a checked exception that's more suitable for an API. There is an example here:
http://radio-weblogs.com/0122027/stories/2003/04/01/JavasCheckedExceptionsWereAMistake.html

If you look at exceptions as on an alternative way to get a method result, then re-throwing an exception is like wrapping your result into some other object.
And this is a common operation in a non-exceptional world. Usually this happens on a border of two application layers - when a function from layer B calls a function from layer C, it transforms C's result into B's internal form.
A -- calls --> B -- calls --> C
If it doesn't, then at the layer A which calls the layer B there will be a full set of JDK exceptions to handle. :-)
As also the accepted answer points out, layer A might not even be aware of C's exception.
Example
Layer A, servlet: retrieves an image and it's meta information
Layer B, JPEG library: collects available DCIM tags to parse a JPEG file
Layer C, a simple DB: a class reading string records from a random access file. Some bytes are broken, so it throws an exception saying "can't read UTF-8 string for record 'bibliographicCitation'".
So A won't understand the meaning of 'bibliographicCitation'. So B should translate this exception for A into TagsReadingException which wraps the original.

THE MAIN REASON of re-throwing exceptions is to leave Call Stack untouched, so you can get more complete picture of what happens and calls sequence.

Related

Strategies to avoid adding try/catch to every method block in a codebase?

It is quite tiresome writing try/catches in every method block.
Apart from AOP, is there any way to avoid this and catch all exceptions? Would it be enough to just catch them at the global error handler level (e.g. as in ASP.NET).
Thanks
The best advice I've heard on the subject (somewhere on SO, actually) was "only catch an exception if you're going to handle it." That is, it only makes sense to use a catch block in that method if that method has the means of handling the exception. For example, if the method should for some reason always return a value, and the exception is either silently logged or somehow indicated in the value (such as an error message attached to some custom DTO or something). There's nothing wrong with bubbling the exception upward in the stack and assuming the caller will handle it.
That's not to say, of course, that it shouldn't be handled at all. As you suggest, the last line of defense should always be the global exception handling for the application. All fails should be handled gracefully, but they should more importantly be handled only by the class/method that is supposed to handle them, which in many cases is not the method from which the exception originated. For example, in a simple forms over data web app, the data access doesn't necessarily need to handle the exception. It can add information to it if pertinent, but for such a simple app the global error handler can take care of logging and presenting an error message.
It should also be noted (I'm assuming you're talking about .NET here) that a try block need not always be accompanied by a catch block. You can try{}finally{} to take care of cleaning up after an exception (such as gracefully closing an external resource) without bothering to catch the exception and instead let it bubble up accordingly.
I agree with David. Here's my basic set of rules, or ... like the pirate code, guidelines ...
There should always be one global exception handler to catch runtimes and anything else that the classes cannot handle.
Try/catch should only be implemented when you can actually do something about the exception. And No, logging the exception is not doing something about it.
Adding a throws or Throwing a Exception or RuntimeException should be avoided. If you have a wide or large number of exceptions to deal with, create a new exception class to wrap them. Exception is too general and creates problems for other developers.
Try/catch blocks are expensive, do don't put them in unless necessary.
Never, and I mean NEVER !!! use try/catch for logic flow.
I've found it helpful to think of your code as having three layers, and using an exception strategy appropriate to each layer. I wrote up the details in Exceptions in the Rainforest.

Why not catch general Exceptions

My VS just told me;
Warning 2 CA1031 : Microsoft.Design : Modify 'Program.Main(string[])' to catch a more specific exception than 'Exception' or rethrow the exception.
Why should I do that? If I do so, and don't catch all exceptions to handle them, my program crashes with the all-popular report-screen. I don't want my users to get such error-crap!
Why should I not catch all exceptions at once to display a nice warning to the user saying: "Something went wrong, don't care about it, I will handle it, just be patient"?
Edit: Just saw I have a dupe here, sorry for that Dupe
Edit2: To clarify things; I do exit the program after any exception has been catched! I just don't want my user to see that "report to microsoft" dialog that show up when an unhandled exception is raised in a console-application!
Swallowing exceptions is a dangerous practice because:
It can cause the user to think something succeeded when it actually failed.
It can put your application into states that you didn't plan for.
It complicates debugging, since it's much harder to find out where the failure happened when you're dealing with bizarre/broken behavior instead of a stack trace.
As you can probably imagine, some of these outcomes can be extremely catastrophic, so doing this right is an important habbit.
Best Practice
First off, code defensively so that exceptions don't occur any more than necessary. They're computationally expensive.
Handle the expected exceptions at a granular level (for example: FileNotFoundException) when possible.
For unexpected exceptions, you can do one of two things:
Let them bubble up normally and cause a crash
Catch them and fail gracefully
Fail Gracefully?
Let's say you're working in ASP.Net and you don't want to show the yellow screen of death to your users, but you also don't want problems to be hidden from the dev team.
In our applications, we usually catch unhandled exceptions in global.asax and then do logging and send out notification emails. We also show a more friendly error page, which can be configured in web.config using the customErrors tag.
That's our last line of defense, and if we end up getting an email we jump on it right away.
That type of pattern is not the same as just swallowing exceptions, where you have an empty Catch block that only exists to "pretend" that the exception did not occur.
Other Notes
In VS2010, there's something called intellitrace coming that will allow you to actually email the application state back home and step through code, examine variable values at the time of the exception, and so on. That's going to be extremely useful.
Because programs that swallow (catch) exceptions indiscriminately, (and then continue), cannot be relied upon to do what it is they are expected to do. This is because you have no idea what kind of exception was "ignored". What if there was an overflow or memory access error that causes the wrong amount to be debited from a financial account? What if it steers the ship into the iceberg instead of away from it ? Unexpected failures should always cause the application to terminate. That forces the development process to identify and correct the exceptions it finds, (crashes during demos are a wonderful motivator), and, in production, allows appropriately designed backup systems to react when the software experiences an "unexpected" inability to do what it was designed to do.
EDIT: To clarify distinctions between UI components, and service or middleware componentrs.
In Service or Middleware components, where there is no user interacting with the code component from within the same process space that the code is running in, the component needs to "pass On" the exception to whatever client component imnitiated the call it is currently processing. No matter the exception, it should make every possible attempt to do this. It is still the case, however, tjhat in cases where an unexpected, or unanticipated exception occurs, the component should finally terminate the process it is running in. For anticipated or expected exceptions, a velopment analysis should be done to determine whether or not, for that specific exception, the component and it's host process can continue to operate (handling future requests), or whether it should be terminated.
You should handle the exact exceptions you are capable of handling and let all others bubble up. If it displays a message to the user that means you don't quite know what you can handle.
Having worked on equipment used by emergency responders, I would rather the user see an ugly error message than to accidently swallow an exception that misleads the user into believing everything is "ok". Depending on your application, the consequence could be anything from nothing to a lost sale to a catastrophic loss of life.
If a person were going to catch all exception, show a better error dialog, and then quit the application, that's ok.. but if they are going to continue running after swallowing an unknown exception, I would fire a person for that. It's not ok. Ever.
Good coding is about practices that assume humans make mistakes. Assuming all "critical" exceptions have been caught and handled is a bad idea.
Simple answer: you are supposed to fix your bug. Find the place that throws the exception and unless it is beyond your control - fix it.
Also catching (without rethrowing) all kinds of exception violates exception neutrality. In general you do not want to do this (although catching exceptions in main does look like special case)
Since your warning message shows that this is in Main(), I'll assume that in lower levels, you do catch only more specific Exceptions.
For Main(), I'd consider two cases:
Your own (debugging) build, where you want all the exception information you can get: Do not catch any Exceptions here, so the debugger breaks and you have your call stack,
Your public releases, where you want the application to behave normally: Catch Exception and display a nice message. This is always better (for the average user) than the 'send report' window.
To do this nicely, just check if DEBUG is defined (and define it, if VS doesn't do this automatically):
#if DEBUG
yadda(); // Check only specific Exception types here
#else
try
{
yadda();
}
catch (Exception e)
{
ShowMessage(e); // Show friendly message to user
}
#endif
I'd disable the warning about catching general Exceptions, but only for your Main() function, catching Exception in any other method is unwise, as other posters have said already.
There is a way to suppress certain messages from code analysis. I've used this for this exact reason (catching the general exception for logging purposes) and it's been pretty handy. When you add this attribute, it shows you've at least acknowledged that you are breaking the rule for a specific reason. You also still get your warning for catch blocks that are incorrect (catching the general exception for purposes other than logging).
MSDN SuppressMessageAttribute
I am all for catching specific known exceptions and handling state...but I use general catch exceptions to quickly localize problems and pass errors up to calling methods which handle state just fine. During development as those are caught, they have a place right next to the general exception and are handled once in release.
I believe one should attempt to remove these once the code goes into production, but to constantly be nagged during the initial code creation is a bit much.
Hence turn off (uncheck) the warning by the project settings as found in Microsoft.CodeQuality.Analyzers. That is found in the project settings under Code Analysis:
All answers are good here. But I would mention one more option.
The intention of author to show some fancy message is understandable.
Also, default Windows error message is really ugly. Besides, if application is not submitted to "Windows Excellence Program" the developer will not receive information about this problem. So what is the point to use default runtime handler if it does not help?
The thing here is that default exception handler of CLR host ( https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2008/9x0wh2z3(v=vs.90)?redirectedfrom=MSDN ) works in a very safe way. The purpose of it is clear: log the error, send it to developer, set the return code of your process and kill it. The general way of how to change that is to write your own host. In this case you can provide your own way of handling exceptions.
Still, there is an easy solution which satisfies CA1031 and still most of your needs.
When catching the exception, you can handle it your own way (log, show the message etc) and at the end you can set the process result code and do the exit (using the mix of Thread.Abort and "Exit" methods, for example). Still, at the end of your catch block you can just put "throw;" (which will never be called because of ThreadAbortedException, but will satisfy the rule). Still there are some cases, like StackOverflowException, which can't be handled like that and you will see that default message box, for fixing which you need to fallback to custom CLR host option.
Additionally, just for your information, you application can run several threads (besides that one which execute Main method). To receive exceptions from all of them you can use AppDomain.UnhandledException. This event does not allow you to "mark" the exception as handled, still you can freeze the thread using Thread.Join() and then do the job (log, msgbox, exit) using another (one more) thread.
I understand all this looks a little tricky and may be not right, but we have to deal with the implementation of AppDomain.UnhandledException, ThreadAbortException, CorruptedState exceptions and default CLR host. All of this eventually does not leave us much of choice.
When you catch general exceptions, you get the side effect of potentially hiding run-time problems from the user which, in turn, can complicate debugging. Also, by catching general exception, you're ignoring a problem (which you're probably throwing elsewhere).
You can set up your try catch to catch multiple different behavior types and handle the exception based on the type. For most methods and properties in the framework, you can also see what exceptions they are capable of throwing. So unless you are catching an exception from an extremely small block of code, you should probably catch specific exceptions.
In VS you can setup a custom error page to show your users when something goes wrong instead of catching it in a try-catch. I'm assuming since you're using VS that you're using ASP .NET. If so add this tag to your Web.Config under the System.Web tag:
<customErrors mode="RemoteOnly" defaultRedirect="~/CustomErrorPage.aspx" redirectMode="ResponseRewrite" />
You can also catch all uncaught exceptions in the Global.asax file (if you don't have it already: Right-click on web project, select Add Item, and search for it). There are a bunch of application wide event handlers in that file like "Application_Error" that catches every exception that isn't caught within your application so you don't have to use Try-Catch all the time. This is good to use to send yourself an email if an exception occurs and possibly redirect them to your homepage or something if you don't want to use the customErrors tag above.
But ultimately you don't want to wrap your entire application in a try-catch nor do you want to catch a general Exception. Try-catches generally slow down your application and a lot of times if you catch every general exception than it could be possible that you wouldn't know a bug exists until months or years later because the try-catch caused you to overlook it.

Exceptions over remote methods

What are the best practices for exceptions over remote methods?
I'm sure that you need to handle all exceptions at the level of a remote method implementation, because you need to log it on the server side. But what should you do afterwards?
Should you wrap the exception in a RemoteException (java) and throw it to the client? This would mean that the client would have to import all exceptions that could be thrown. Would it be better to throw a new custom exception with fewer details? Because the client won't need to know all the details of what went wrong. What should you log on the client? I've even heard of using return codes(for efficiency maybe?) to tell the caller about what happened.
The important thing to keep in mind, is that the client must be informed of what went wrong. A generic answer of "Something failed" or no notification at all is unacceptable. And what about runtime (unchecked) exceptions?
It seems like you want to be able to differentiate if the failure was due to a system failure (e.g. a service or machine is down) or a business logic failure (e.g. the user does not exist).
I'd recommend wrapping all system exceptions from the RMI call with your own custom exception. You can still maintain the information in the exception by passing it to your custom exception as the cause (this is possible in Java, not sure about other languages). That way client only need to know how to handle the one exception in the cause of system failure. Whether this custom exception is checked or runtime is up for debate (probably depends on your project standards). I would definitely log this type of failure.
Business type failures can be represented as either a separate exception or some type of default (or null) response object. I would attempt to recover (i.e. take some alternative action) from this type of failure and log only if the recovery fails.
In past projects we'd catch all service layer (tier) exceptions at the very top of the layer, passing the application specific error codes/information to the UI via DTO's/VO's. It's a simple approach in that there's an established pattern of all error handling happening in the same place for each service instead of scattered about the service and UI layers.
Then all the UI has to do is inspect the DTO/VO for a flag (hasError?) and display the error message(s), it doesn't have to know nor care what the actual exception was.
I would always log the exception within my application (at the server side as defined in your question).
I would then throw an exception, to be caught by the client. If the caller could take corrective action to prevent the exception then I would ensure that the exception contained this information (e.g. DateTime argName must not be in the past). If the error was caused by some outage of a third party system then I might pass this information up the call stack to the caller.
If, however, the exception was essentially caused by a bug in my system then I would structure my exception handling such that a non-informative exception message (e.g. General failure) was used.
Here's what I did. Every Remote Method implementation catches all Exceptions on the server side and logs them. Then they are wrapped in a Custom Exception, which will contain a description of the problem. This description must be useful to the client, so it won't contain all the details of the caught Exception, because the client doesn't need them. They have already been logged on the server side. Now, on the client, these Exceptions can be handled how the user wishes.
Why I chose using Exceptions and not return codes is because of one very important drawback of return codes: you can't throw them to higher levels without some effort. This means you have to check for an error right after the call and handle it there. But this may not be what I want.

When to rethrow an exception, when to return FALSE?

I am developing a wrapper for a third party function library that is interfacing with some special hardware. So basically, I want to encapsulate the dll functions (bool Connect(), void Disconnect() etc) in a MyHardwareObject with connect- and disconnect methods.
The Connect function from the dll can throw some specific exceptions, for example when the hardware is not present. For the application, the information on why the connect method failed is considered unimportant, so the additional information contained in the exception is not needed.
What is the best way of handling those exceptions, returning false, or leaving the exception unhandled here and catch it on the level that would otherwise handle the fact that the connect method returnded false?
bool MyHardwareObject.Connect()
{
try
{
ThirdPartyLibrary.Connect();
}
catch (SomeException)
{
return false;
}
return true;
}
As opposed to
bool MyHardwareObject.Connect()
{
ThirdPartyLibrary.Connect();
return true;
}
(or in the second case better void MyHardwareObject.Connect(), since we either return true, or throw an exception?)
Or what else would you do? And most important: Why?
In my opinion the first case is certainly better than the second. You want your hardware library to wrap around the third-party library in a way that your users don't have to know exactly what's in it.
If you need more detail in the error handling besides true or false, you could consider rethrowing your own exception, translating the exception from the third party library to something more consistent with your own code.
It's really difficult to choose wisely between exceptions and return codes. It depends on a lot of things, and how errors are handled in the rest of your codebase would be the most important one - stay consistent.
Lately, I'm leaning more towards the "don't throw an exception if it's not worth it". Our exceptions do a lot of work: they log stuff, they create stack traces, etc. If I just want to convert a string to an integer, throwing an exception if the input string has the wrong format is probably not worth it. On the other hand, I have objects that I simply don't want in my system if they can't be constructed from proper data, and in that case their constructors throw exceptions.
If the rest of the codebase does not give you any hint on how to do it, I like this rule of thumb: imagine that throwing an exception makes your computer emit a loud beep. As long as you can put up with it, throwing is fine.
I would pass on the exceptions. If you don't you are masking potentially important information that could be useful later. I know that you aren't using it now, but what if you decide in the future to handle recovery differently based on the type of error. At that point you will have to undo all the code that you've written to mask out the exception. While I disagree with #MadKeithV on making it true/false, I think he has a point on wrapping the exception in your own exception that has, possibly, better semantics for your applicaiton.
Read this: http://www.onjava.com/pub/a/onjava/2003/11/19/exceptions.html
In short:
Does the caller have any use for the return value? Can it recover or is an error the end of the world? If it's just a minor issue, use a return code. If the various states happen equally often (50% of the time it fails, 50% it works), use a return code because the caller must handle the situation anyway and an exception doesn't help.
Do you want to pass up additional information (like the setup of the third party thingy so someone has a chance to debug what happened later)? Use an exception.
I would suggest the second one. It will be the caller responsibility to handle the exception and take the right action according to the exception.
Suppose Connect throws AccountExpiredException, NetworkUnavailableException, InvalidCredentialsException, etc (these are just examples) I can prompt the user to "fix" the exception (Contact the Administrator, Check you network cable, Check Username/Password).
I would even suggest to remove the return value(indicator) and just make it void. Take a look at SqlConnection Open method - it's like you Connect - it doesn't return a value instead it throws an exception.
To swallow the exception like this
bool MyHardwareObject.Connect()
{
try
{
ThirdPartyLibrary.Connect();
}
catch (SomeException)
{
return false;
}
return true;
}
isn't a good idea IMHO. I would recommend you to implement IDisposable pattern.
Just my 2 cents.
Is this third-party library required for your program to run, or does it just add a little extra functionality, which, while nice, is not required? Also, is it likely that the hardware will fail. Finally, how many types of exceptions can the hardware throw at you?
If the library is not actually needed for your program to run, you certainly need to catch the exception at some point, but you may want to do it higher up.
If the hardware can throw multiple types of exceptions, it is more likely that you would want to rethrow the exception since simply returning a value will cause you to lose some of the information. However, you did say that the client doesn't care why it failed, just that it did, so this shouldn't be an issue.
Finally, if the hardware failure is commonplace, you might be more likely to want to return an error code (or false in this case) than if failure is commonplace.
I think in your case it really comes down to the first question. If you don't really need this library, return false and make sure that it is very clearly documented that the operation may fail for completely arbitrary reasons and that they need to check the return value. If you need it to work, rethrow the exception and let it propogate to wherever you can gracefully exit.
I believe the principle behind the exception mechanism is the "fail fast" theory.
Do you want your client's application to "fail fast" is the connection is unsuccessful ?
If yes, just throw back the exception or encapsulate the exception in an applicative exception of your own.
If the client ignore that exception, his application will stop.
Return false means the client might ignore the problem, his application might still crash, but "later"...

When to throw an exception?

I have exceptions created for every condition that my application does not expect. UserNameNotValidException, PasswordNotCorrectException etc.
However I was told I should not create exceptions for those conditions. In my UML those ARE exceptions to the main flow, so why should it not be an exception?
Any guidance or best practices for creating exceptions?
My personal guideline is: an exception is thrown when a fundamental assumption of the current code block is found to be false.
Example 1: say I have a function which is supposed to examine an arbitrary class and return true if that class inherits from List<>. This function asks the question, "Is this object a descendant of List?" This function should never throw an exception, because there are no gray areas in its operation - every single class either does or does not inherit from List<>, so the answer is always "yes" or "no".
Example 2: say I have another function which examines a List<> and returns true if its length is more than 50, and false if the length is less. This function asks the question, "Does this list have more than 50 items?" But this question makes an assumption - it assumes that the object it is given is a list. If I hand it a NULL, then that assumption is false. In that case, if the function returns either true or false, then it is breaking its own rules. The function cannot return anything and claim that it answered the question correctly. So it doesn't return - it throws an exception.
This is comparable to the "loaded question" logical fallacy. Every function asks a question. If the input it is given makes that question a fallacy, then throw an exception. This line is harder to draw with functions that return void, but the bottom line is: if the function's assumptions about its inputs are violated, it should throw an exception instead of returning normally.
The other side of this equation is: if you find your functions throwing exceptions frequently, then you probably need to refine their assumptions.
Because they're things that will happen normally. Exceptions are not control flow mechanisms. Users often get passwords wrong, it's not an exceptional case. Exceptions should be a truly rare thing, UserHasDiedAtKeyboard type situations.
My little guidelines are heavily influenced by the great book "Code complete":
Use exceptions to notify about things that should not be ignored.
Don't use exceptions if the error can be handled locally
Make sure the exceptions are at the same level of abstraction as the rest of your routine.
Exceptions should be reserved for what's truly exceptional.
It is NOT an exception if the username is not valid or the password is not correct. Those are things you should expect in the normal flow of operation. Exceptions are things that are not part of the normal program operation and are rather rare.
I do not like using exceptions because you can not tell if a method throws an exception just by looking at the call. Thats why exceptions should only be used if you can't handle the situation in a decent manner (think "out of memory" or "computer is on fire").
One rule of thumb is to use exceptions in the case of something you couldn't normally predict. Examples are database connectivity, missing file on disk, etc. For scenarios that you can predict, ie users attempting to log in with a bad password you should be using functions that return booleans and know how to handle the situation gracefully. You don't want to abruptly end execution by throwing an exception just because someone mistyped their password.
Others propose that exceptions should not be used because the bad login is to be expected in a normal flow if the user mistypes. I disagree and I don't get the reasoning. Compare it with opening a file.. if the file doesn't exist or is not available for some reason then an exception will be thrown by the framework. Using the logic above this was a mistake by Microsoft. They should have returned an error code. Same for parsing, webrequests, etc., etc..
I don't consider a bad login part of a normal flow, it's exceptional. Normally the user types the correct password, and the file does exist. The exceptional cases are exceptional and it's perfectly fine to use exceptions for those. Complicating your code by propagating return values through n levels up the stack is a waste of energy and will result in messy code. Do the simplest thing that could possibly work. Don't prematurely optimize by using error codes, exceptional stuff by definition rarely happens, and exceptions don't cost anything unless you throw them.
I think you should only throw an exception when there's nothing you can do to get out of your current state. For example if you are allocating memory and there isn't any to allocate. In the cases you mention you can clearly recover from those states and can return an error code back to your caller accordingly.
You will see plenty of advice, including in answers to this question, that you should throw exceptions only in "exceptional" circumstances. That seems superficially reasonable, but is flawed advice, because it replaces one question ("when should I throw an exception") with another subjective question ("what is exceptional"). Instead, follow the advice of Herb Sutter (for C++, available in the Dr Dobbs article When and How to Use Exceptions, and also in his book with Andrei Alexandrescu, C++ Coding Standards): throw an exception if, and only if
a precondition is not met (which typically makes one of the following
impossible) or
the alternative would fail to meet a post-condition or
the alternative would fail to maintain an invariant.
Why is this better? Doesn't it replace the question with several questions about preconditions, postconditions and invariants? This is better for several connected reasons.
Preconditions, postconditions and invariants are design characteristics of our program (its internal API), whereas the decision to throw is an implementation detail. It forces us to bear in mind that we must consider the design and its implementation separately, and our job while implementing a method is to produce something that satisfies the design constraints.
It forces us to think in terms of preconditions, postconditions and invariants, which are the only assumptions that callers of our method should make, and are expressed precisely, enabling loose coupling between the components of our program.
That loose coupling then allows us to refactor the implementation, if necessary.
The post-conditions and invariants are testable; it results in code that can be easily unit tested, because the post-conditions are predicates our unit-test code can check (assert).
Thinking in terms of post-conditions naturally produces a design that has success as a post-condition, which is the natural style for using exceptions. The normal ("happy") execution path of your program is laid out linearly, with all the error handling code moved to the catch clauses.
Exceptions are a somewhat costly effect, if for example you have a user that provides an invalid password, it is typically a better idea to pass back a failure flag, or some other indicator that it is invalid.
This is due to the way that exceptions are handled, true bad input, and unique critical stop items should be exceptions, but not failed login info.
I would say there are no hard and fast rules on when to use exceptions. However there are good reasons for using or not using them:
Reasons to use exceptions:
The code flow for the common case is clearer
Can return complex error information as an object (although this can also be achieved using error "out" parameter passed by reference)
Languages generally provide some facility for managing tidy cleanup in the event of the exception (try/finally in Java, using in C#, RAII in C++)
In the event no exception is thrown, execution can sometimes be faster than checking return codes
In Java, checked exceptions must be declared or caught (although this can be a reason against)
Reasons not to use exceptions:
Sometimes it's overkill if the error handling is simple
If exceptions are not documented or declared, they may be uncaught by calling code, which may be worse than if the the calling code just ignored a return code (application exit vs silent failure - which is worse may depend on the scenario)
In C++, code that uses exceptions must be exception safe (even if you don't throw or catch them, but call a throwing function indirectly)
In C++, it is hard to tell when a function might throw, therefore you must be paranoid about exception safety if you use them
Throwing and catching exceptions is generally significantly more expensive compared to checking a return flag
In general, I would be more inclined to use exceptions in Java than in C++ or C#, because I am of the opinion that an exception, declared or not, is fundamentally part of the formal interface of a function, since changing your exception guarantee may break calling code. The biggest advantage of using them in Java IMO, is that you know that your caller MUST handle the exception, and this improves the chance of correct behaviour.
Because of this, in any language, I would always derive all exceptions in a layer of code or API from a common class, so that calling code can always guarantee to catch all exceptions. Also I would consider it bad to throw exception classes that are implementation-specific, when writing an API or library (i.e. wrap exceptions from lower layers so that the exception that your caller receives is understandable in the context of your interface).
Note that Java makes the distinction between general and Runtime exceptions in that the latter need not be declared. I would only use Runtime exception classes when you know that the error is a result of a bug in the program.
If it's code running inside a loop that will likely cause an exception over and over again, then throwing exceptions is not a good thing, because they are pretty slow for large N. But there is nothing wrong with throwing custom exceptions if the performance is not an issue. Just make sure that you have a base exception that they all inherite, called BaseException or something like that. BaseException inherits System.Exception, but all of your exceptions inherit BaseException. You can even have a tree of Exception types to group similar types, but this may or may not be overkill.
So, the short answer is that if it doesn't cause a significant performance penalty (which it should not unless you are throwing a lot of exceptions), then go ahead.
Exception classes are like "normal" classes. You create a new class when it "is" a different type of object, with different fields and different operations.
As a rule of thumb, you should try balance between the number of exceptions and the granularity of the exceptions. If your method throws more than 4-5 different exceptions, you can probably merge some of them into more "general" exceptions, (e.g. in your case "AuthenticationFailedException"), and using the exception message to detail what went wrong. Unless your code handles each of them differently, you needn't creates many exception classes. And if it does, may you should just return an enum with the error that occured. It's a bit cleaner this way.
the rule of thumb for throwing exceptions is pretty simple. you do so when your code has entered into an UNRECOVERABLE INVALID state. if data is compromised or you cannot wind back the processing that occurred up to the point then you must terminate it. indeed what else can you do? your processing logic will eventually fail elsewhere. if you can recover somehow then do that and do not throw exception.
in your particular case if you were forced to do something silly like accept money withdrawal and only then check user/pasword you should terminate the process by throwing an exception to notify that something bad has happened and prevent further damage.
I agree with japollock way up there--throw an acception when you are uncertain about the outcome of an operation. Calls to APIs, accessing filesystems, database calls, etc. Anytime you are moving past the "boundaries" of your programming languages.
I'd like to add, feel free to throw a standard exception. Unless you are going to do something "different" (ignore, email, log, show that twitter whale picture thingy, etc), then don't bother with custom exceptions.
I'd say that generally every fundamentalism leads to hell.
You certainly wouldn't want to end up with exception driven flow, but avoiding exceptions altogether is also a bad idea. You have to find a balance between both approaches. What I would not do is to create an exception type for every exceptional situation. That is not productive.
What I generally prefer is to create two basic types of exceptions which are used throughout the system: LogicalException and TechnicalException. These can be further distinguished by subtypes if needed, but it is not generally not necessary.
The technical exception denotes the really unexpected exception like database server being down, the connection to the web service threw the IOException and so on.
On the other hand the logical exceptions are used to propagate the less severe erroneous situation to the upper layers (generally some validation result).
Please note that even the logical exception is not intended to be used on regular basis to control the program flow, but rather to highlight the situation when the flow should really end. When used in Java, both exception types are RuntimeException subclasses and error handling is highly aspect oriented.
So in the login example it might be wise to create something like AuthenticationException and distinguish the concrete situations by enum values like UsernameNotExisting, PasswordMismatch etc. Then you won't end up in having a huge exception hierarchy and can keep the catch blocks on maintainable level. You can also easily employ some generic exception handling mechanism since you have the exceptions categorized and know pretty well what to propagate up to the user and how.
Our typical usage is to throw the LogicalException during the Web Service call when the user's input was invalid. The Exception gets marshalled to the SOAPFault detail and then gets unmarshalled to the exception again on the client which is resulting in showing the validation error on one certain web page input field since the exception has proper mapping to that field.
This is certainly not the only situation: you don't need to hit web service to throw up the exception. You are free to do so in any exceptional situation (like in the case you need to fail-fast) - it is all at your discretion.
In general you want to throw an exception for anything that can happen in your application that is "Exceptional"
In your example, both of those exceptions look like you are calling them via a password / username validation. In that case it can be argued that it isn't really exceptional that someone would mistype a username / password.
They are "exceptions" to the main flow of your UML but are more "branches" in the processing.
If you attempted to access your passwd file or database and couldn't, that would be an exceptional case and would warrant throwing an exception.
Firstly, if the users of your API aren't interested in specific, fine-grained failures, then having specific exceptions for them isn't of any value.
Since it's often not possible to know what may be useful to your users, a better approach is to have the specific exceptions, but ensure they inherit from a common class (e.g., std::exception or its derivatives in C++). That allows your client to catch specific exceptions if they choose, or the more general exception if they don't care.
Exceptions are intended for events that are abnormal behaviors, errors, failures, and such. Functional behavior, user error, etc., should be handled by program logic instead. Since a bad account or password is an expected part of the logic flow in a login routine, it should be able to handle those situations without exceptions.
The simple answer is, whenever an operation is impossible (because of either application OR because it would violate business logic). If a method is invoked and it impossible to do what the method was written to do, throw an Exception. A good example is that constructors always throw ArgumentExceptions if an instance cannot be created using the supplied parameters. Another example is InvalidOperationException, which is thrown when an operation cannot be performed because of the state of another member or members of the class.
In your case, if a method like Login(username, password) is invoked, if the username is not valid, it is indeed correct to throw a UserNameNotValidException, or PasswordNotCorrectException if password is incorrect. The user cannot be logged in using the supplied parameter(s) (i.e. it's impossible because it would violate authentication), so throw an Exception. Although I might have your two Exceptions inherit from ArgumentException.
Having said that, if you wish NOT to throw an Exception because a login failure may be very common, one strategy is to instead create a method that returns types that represent different failures. Here's an example:
{ // class
...
public LoginResult Login(string user, string password)
{
if (IsInvalidUser(user))
{
return new UserInvalidLoginResult(user);
}
else if (IsInvalidPassword(user, password))
{
return new PasswordInvalidLoginResult(user, password);
}
else
{
return new SuccessfulLoginResult();
}
}
...
}
public abstract class LoginResult
{
public readonly string Message;
protected LoginResult(string message)
{
this.Message = message;
}
}
public class SuccessfulLoginResult : LoginResult
{
public SucccessfulLogin(string user)
: base(string.Format("Login for user '{0}' was successful.", user))
{ }
}
public class UserInvalidLoginResult : LoginResult
{
public UserInvalidLoginResult(string user)
: base(string.Format("The username '{0}' is invalid.", user))
{ }
}
public class PasswordInvalidLoginResult : LoginResult
{
public PasswordInvalidLoginResult(string password, string user)
: base(string.Format("The password '{0}' for username '{0}' is invalid.", password, user))
{ }
}
Most developers are taught to avoid Exceptions because of the overhead caused by throwing them. It's great to be resource-conscious, but usually not at the expense of your application design. That is probably the reason you were told not to throw your two Exceptions. Whether to use Exceptions or not usually boils down to how frequently the Exception will occur. If it's a fairly common or an fairly expectable result, this is when most developers will avoid Exceptions and instead create another method to indicate failure, because of the supposed consumption of resources.
Here's an example of avoiding using Exceptions in a scenario like just described, using the Try() pattern:
public class ValidatedLogin
{
public readonly string User;
public readonly string Password;
public ValidatedLogin(string user, string password)
{
if (IsInvalidUser(user))
{
throw new UserInvalidException(user);
}
else if (IsInvalidPassword(user, password))
{
throw new PasswordInvalidException(password);
}
this.User = user;
this.Password = password;
}
public static bool TryCreate(string user, string password, out ValidatedLogin validatedLogin)
{
if (IsInvalidUser(user) ||
IsInvalidPassword(user, password))
{
return false;
}
validatedLogin = new ValidatedLogin(user, password);
return true;
}
}
for me Exception should be thrown when a required technical or business rule fails.
for instance if a car entity is associated with array of 4 tires ... if one tire or more are null ... an exception should be Fired "NotEnoughTiresException" , cuz it can be caught at different level of the system and have a significant meaning through logging.
besides if we just try to flow control the null and prevent the instanciation of the car .
we might never never find the source of the problem , cuz the tire isn't supposed to be null in the first place .
the main reason for avoiding throwing an exception is that there is a lot of overhead involved with throwing an exception.
One thing the article below states is that an exception is for an exceptional conditions and errors.
A wrong user name is not necessarily a program error but a user error...
Here is a decent starting point for exceptions within .NET:
http://msdn.microsoft.com/en-us/library/ms229030(VS.80).aspx
Throwing exceptions causes the stack to unwind, which has some performance impacts (admitted, modern managed environments have improved on that). Still repeatedly throwing and catching exceptions in a nested situation would be a bad idea.
Probably more important than that, exceptions are meant for exceptional conditions. They should not be used for ordinary control flow, because this will hurt your code's readability.
I have three type of conditions that I catch.
Bad or missing input should not be an exception. Use both client side js and server side regex to detect, set attributes and forward back to the same page with messages.
The AppException. This is usually an exception that you detect and throw with in your code. In other words these are ones you expect (the file does not exist). Log it, set the message, and forward back to the general error page. This page usually has a bit of info about what happened.
The unexpected Exception. These are the ones you don't know about. Log it with details and forward them to a general error page.
Hope this helps
Security is conflated with your example: You shouldn't tell an attacker that a username exists, but the password is wrong. That's extra information you don't need to share. Just say "the username or password is incorrect."
I have philosophical problems with the use of exceptions. Basically, you are expecting a specific scenario to occur, but rather than handling it explicitly you are pushing the problem off to be handled "elsewhere." And where that "elsewhere" is can be anyone's guess.
To my mind, the fundamental question should be whether one would expect that the caller would want to continue normal program flow if a condition occurs. If you don't know, either have separate doSomething and trySomething methods, where the former returns an error and the latter does not, or have a routine that accepts a parameter to indicate whether an exception should be thrown if it fails). Consider a class to send commands to a remote system and report responses. Certain commands (e.g. restart) will cause the remote system to send a response but then be non-responsive for a certain length of time. It is thus useful to be able to send a "ping" command and find out whether the remote system responds in a reasonable length of time without having to throw an exception if it doesn't (the caller would probably expect that the first few "ping" attempts would fail, but one would eventually work). On the other hand, if one has a sequence of commands like:
exchange_command("open tempfile");
exchange_command("write tempfile data {whatever}");
exchange_command("write tempfile data {whatever}");
exchange_command("write tempfile data {whatever}");
exchange_command("write tempfile data {whatever}");
exchange_command("close tempfile");
exchange_command("copy tempfile to realfile");
one would want failure of any operation to abort the whole sequence. While one could check each operation to ensure it succeeded, it's more helpful to have the exchange_command() routine throw an exception if a command fails.
Actually, in the above scenario it may be helpful to have a parameter to select a number of failure-handling modes: never throw exceptions, throw exceptions for communication errors only, or throw exceptions in any cases where a command does not return a "success" indication.
You may use a little bit generic exceptions for that conditions. For e.g. ArgumentException is meant to be used when anything goes wrong with the parameters to a method (with the exception of ArgumentNullException). Generally you would not need exceptions like LessThanZeroException, NotPrimeNumberException etc. Think of the user of your method. The number of the conditions that she will want to handle specifically is equal to the number of the type of the exceptions that your method needs to throw. This way, you can determine how detailed exceptions you will have.
By the way, always try to provide some ways for users of your libraries to avoid exceptions. TryParse is a good example, it exists so that you don't have to use int.Parse and catch an exception. In your case, you may want to provide some methods to check if user name is valid or password is correct so your users (or you) will not have to do lots of exception handling. This will hopefully result in more readble code and better performance.
Ultimately the decision comes down to whether it is more helpful to deal with application-level errors like this using exception handling, or via your own home-rolled mechanism like returning status codes. I don't think there's a hard-and-fast rule about which is better, but I would consider:
Who's calling your code? Is this a public API of some sort or an internal library?
What language are you using? If it's Java, for example, then throwing a (checked) exception puts an explicit burden on your caller to handle this error condition in some way, as opposed to a return status which could be ignored. That could be good or bad.
How are other error conditions in the same application handled? Callers won't want to deal with a module that handles errors in an idiosyncratic way unlike anything else in the system.
How many things can go wrong with the routine in question, and how would they be handled differently? Consider the difference between a series of catch blocks that handle different errors and a switch on an error code.
Do you have structured information about the error you need to return? Throwing an exception gives you a better place to put this information than just returning a status.
Some useful things to think about when deciding whether an exception is appropriate:
what level of code you want to have run after the exception candidate occurs - that is, how many layers of the call stack should unwind. You generally want to handle an exception as close as possible to where it occurs. For username/password validation, you would normally handle failures in the same block of code, rather than letting an exception bubble up. So an exception is probably not appropriate. (OTOH, after three failed login attempts, control flow may shift elsewhere, and an exception may be appropriate here.)
Is this event something you would want to see in an error log? Not every exception is written to an error log, but it's useful to ask whether this entry in an error log would be useful - i.e., you would try to do something about it, or would be the garbage you ignore.
"PasswordNotCorrectException" isn't a good example for using exceptions. Users getting their passwords wrong is to be expected, so it's hardly an exception IMHO. You probably even recover from it, showing a nice error message, so it's just a validity check.
Unhandled exceptions will stop the execution eventually - which is good. If you're returning false, null or error codes, you will have to deal with the program's state all by yourself. If you forget to check conditions somewhere, your program may keep running with wrong data, and you may have a hard time figuring out what happened and where.
Of course, you could cause the same problem with empty catch statements, but at least spotting those is easier and doesn't require you to understand the logic.
So as a rule of thumb:
Use them wherever you don't want or simply can't recover from an error.
I would say that exceptions should be thrown if an unexpected behaviour is occuring that wasnt meant to be.
Like trying to update or delete a non existing entity. And it should be catched where the Exception can be handled and has meaning. For working in an alternative way to continue, add logging or returning a specific result on Api level.
If you expect something to be the case, you should build code to check and ensure it.