views:

594

answers:

16

Are there any cases when it's a good idea to throw errors that can be avoided?

I'm thinking specifically of the DivideByZeroException and ArgumentNullException

For example:

double numerator = 10;
double denominator = getDenominator();

if( denominator == 0 ){
   throw new DivideByZeroException("You can't divide by Zero!");
}

Are there any reasons for throwing an error like this?

NOTE: I'm not talking about catching these errors, but specifically in knowing if there are ever good reasons for throwing them.

JUST TO REITERATE:

I KNOW that in the example I gave you'd probably be better off handling the error. Perhaps the question should be rephrased. Are there any reasons to throw one of these errors instead of handling it at this location.

+1  A: 

None that I can think of. I would just program against it. Exceptions can be expensive, so if you can defensively program against it, do that instead of throwing an exception.

At least that's what my senior dev told me when I tried catching a DivideByZeroException many moons ago.

Jack Marchetti
You should defensively program against it, but that doesn't mean you should necessarily assume it will never happen and not catch it. You might be awesome, and handle every UI case...but then, later, someone adds some new features to the UI and they're not as smart...boom. If you can gracefully catch the exception, do any necessary notifcations and logging, and then continue, it can be a good idea.
Beska
good point. but if you always do this: if( denominator == 0 ){} then you wont have the problem. But I see your point.
Jack Marchetti
@Beska - No you should never continue a program in an invalid or unknown state. When unexpected errors occur, the proper notification should be issued and logged, and then the program should die a sudden death. Handling errors "gracefully" is a short path to buggy code and maintenance hell.
Jeffrey L Whitledge
Yeah, and I'm not talking about catching the error... but rather use cases for throwing it. I'm like you, man... I can't think of any reason to `throw` a `DivideByZero` rather than handle it, but there may be edge cases.
Atømix
@Jeffrey: Of course you shouldn't continue in an invalid or unknown state. That's why I said "*if* you can gracefully catch..." Obviously you can't just catch and continue like nothing happened, but in some cases there are ways to continue (query for new correct input and retry, etc.)
Beska
@Jack: Yeah, in this case it's a bit simplified...as you say, a check for "if(denominator==0)" should pretty ensure the argument is moot. But I've also seen cases where people were sure they'd covered all the bases and no bad data could get through...and were eventually proven wrong by weird edge cases, fencepost conditions, etc.
Beska
@atomiton: I know you're talking about cases for throwing as compared to catching it...so this conversation has gone off an a bit off topic...but I was originally responding to the last sentence in this answer: it implies that there's never a good reason to catch one of these exceptions, which is a notion that seems worth challenging.
Beska
A: 

Throwing an exception is an expensive thing to do from a resource point of view. You have already prevented an exception from occurring so why throw one? If you have to tell the user, use some messaging mechanism. If you need to know about it yourself, log it.

Daniel Dyson
Exactly. I agree with you. So, are there ANY cases where one would `throw` a `DivideByZeroException` I can't think of any. That's why I asked the question on SO.
Atømix
If you are not going to throw the exception, what value is your division method going to return in that scenario?
cdkMoose
There is nothing wrong with throwing exceptions. If you are worried about some method could throw and exception you should check the inputs before you call the method or wrap the call in a try/catch block. This should be on the person using the method not the person writing the method.
Matthew Whited
+4  A: 

You should only use an Exception to handle Exceptional cases.

In this case, it looks like a zero would be invalid user input. You should check for invalid user input and handle it accordingly BEFORE you get to the point that an Exception would be approriate.

As long as you properly handle input, there should be no reason for a DivideByZeroException to happen. If you receive a DivideByZeroException even after validating input...then you know you have a real problem (in which case, the Exception is appropriate).

Justin Niessner
I agree with your general point, though I think the old adage of exceptions only being for "exceptional cases" is over stated. Krzysztof Cwalina certainly thinks so - http://blogs.msdn.com/kcwalina/archive/2008/07/17/ExceptionalError.aspx
Dan Diplo
@Dan In my opinion, Krzysztof is just restating the definition of what I consider to be an Exception case (a case in which a real error occurs, not something that could be easily caught with input validation, etc).
Justin Niessner
But if you are writing a library consumed by others...? I think that is the point. The library writer cannot determine in advance what will be exceptional and what will be common place when it comes to how someone consumes their API.
Dan Diplo
That's kind of exactly my question. I know the example is silly... but that's because I'm trying to think of reasons one would `throw` the error. My thinking is if you know it's zero, why throw an Exception... just handle the input! However, there may be cases when you'd want to throw it... that I don't know. Perhaps if you have a View-level try/catch block and you're deep in some nested method. Perhaps you log the error and throw the Exception so you can bubble it out to the user. I don't know... just a random thought.
Atømix
@Atomiton Unless you're writing your own library with a custom division algorithm (where the framework wouldn't already throw the DivisionByZeroException for you), let the .NET framework handle throwing the DivisionByZeroExceptions.
Justin Niessner
Yeah, that's what I'm thinking. A few people have said that it would be used when writing a library. Obviously in normal cases one would either handle the zero or let .Net throw the error. ;-)
Atømix
@Atomiton - Writing a library is the normal case. A typical application has at least three layers, and only the user-interface layer can have all private methods. Each layer may contain many modules. So only a small fraction of the objects in a normal application can avoid validating inputs and throwing exceptions in public methods.
Jeffrey L Whitledge
A: 

Its a good practice to make these checks at top of the function before you start processing data. Rather then throwing them (or any other method throws these exceptions) in the middle of a method.

cornerback84
I agree. That's not what I was asking, though. :-)
Atømix
+3  A: 

If you're talking about code that is directly interacting with the UI, then no. I can't think of any reason why you'd want to.

However, if you're building a class/object used by other devlopers and they've passed in data that is clearly stupid then throw the appropriate error during your validation.

CResults
+7  A: 

The .NET runtime is already very good at throwing these exceptions. They are also highly descriptive of what is wrong, you can't add any good commentary to the exception message. "You can't divide by zero" adds no value.

However, you can avoid many of these exceptions by screening the values passed by the client code. You'll want ArgumentNullException with the name of argument if the client code passed a null, ArgumentException when it passed something that is liable to trip DivideByZero.

Hans Passant
Deleted my answer and voted you up...you said it more clearly than I did. Kudos.
Beska
Definitely this. Even if you're writing a math library, you should not throw DivideByZeroExceptions. For the same reason you should never throw a NullReferenceException, basically: these kinds of exceptions say 'the library is buggy'. What you *want* to say is 'you're using the library wrong'. ArgumentExceptions are perfect.
Joren
If you want to bubble Exceptions out to the user, and use the Exception message to show the user where he went wrong, it may be a good idea to provide a custom message. eg `LiteralErrorMsg1.Text = ex.Message` Another scenario would be Localization. You may want to show the error message in the user's language as well.
Atømix
The stack trace shows where it went wrong. Don't help.
Hans Passant
Oops! I corrected the question. I meant `ArgumentNullException`... not `NullReferenceException`
Atømix
@Atomiton: now your question doesn't make sense anymore. ArgumentNullException is *always* raised by a throw statement. DivideByZeroException is raised by the CPU. Apples and oranges.
Hans Passant
+13  A: 

Let's say you write a library to work with really big integers that don't fit into Int64, then you might want to throw DivideByZeroException for the division algorithm you write.

juharr
Good answer, and you bring up a good edge point.
Beska
Would you be able to elaborate on this one. It sounds like an interesting edge case.
Atømix
@Atomiton - I've actually done exactly this before. If you've written a math library, and the calling code hands you a zero denominator, what else could you possibly do but throw the exception? The math library doesn't know what you're trying to do. There's no always-correct way to handle the situation at that location. Only the calling code has enough of a big-picture view to know what to do about it. So throw the exception.
Jeffrey L Whitledge
@Atomiton Basically if you want numerical precision beyond what fits in Int64 you would have to write your own library (or find one). If you write one you would be creating classes that you would want to do typical mathematical operators on like division. You would want to check for division by zero up front and throw DivideByZeroException to let the users of your library know they are attempting an "exceptional" operation.
juharr
Thanks juharr. Upon thinking about this it's making more sense. I'm having memories of my CS classes a long time ago and writing BigInt classes in Java.
Atømix
Writing a BitInt class in java is easy. It's already in the standard library, and the SDK includes the source to it so...
Malfist
@Malfist: Yeah, I think, though, we had to approach it like we were building our own... and how we would approach it. It was a long time ago, my memory is fuzzy.
Atømix
There are also a lot of other mathematical objects where division makes sense, for example complex numbers or polynomials, and where you can't meaningfully divide by zero.
starblue
A: 

In theory (and practice too), identifying and avoiding/eliminating erroneous cases is better than treating them as exceptions. However, it's not always possible to test every case or path through your code - it's also not possible in every case to control your inputs.

A tenet of good design is to have your program recognize and gracefully handle exceptional situations. Furthermore, it's a good idea to provide your users (and ultimately yourself) enough information to diagnose errors - particularly those that can occur after your code is deployed. Therefore, it does sometimes make sense to throw exceptions such as the kind illustrate if it will make your application code more robust and easier to diagnose.

LBushkin
Can you elaborate a little or provide an example? I'm particularly interested in your second point... that sometimes it IS a good idea to throw expected errors like this (which could otherwise be handled)
Atømix
@Atomiton - I view it as a defensive coding practice. You can never be 100% sure that you really covered all paths and prevented all erroneous data from being passed to a particular body of code. As such, it's worth having logic that detects raises such conditions(when you can) so that in production you can provide enough detail to help rapidly diagnose such issues if they do occur. The basic premise is: proving that a particular input will never be passed to a method is *hard* - checking inputs for validity within the method is much easier.http://en.wikipedia.org/wiki/Defensive_programming
LBushkin
+4  A: 

There is absolutely a reason to do this, and as with most exception throwing questions, you have to think about you as a developer working in a team. What you're writing may be part of another system, or it may be a library or component.

If you write a maths library , and have a function called Divide(int a, int b) that divides them, if someone else wants to use your method and passes in zero, you'll want to throw an exception so they, as a developer, know they've screwed up.

If you don't throw an exception, you introduce bugs into your code. If I used your divide method, and put the values 10 and 0 in, which produces 10/0 and thus an exception, the only correct answer is error. If you decide to change the values so no error occurs, or return 0, that is not what I am expecting - I assume my division worked perfectly, and never notice a problem. I might well take that 0 and go off and use it in other calculations, unaware that it's the wrong answer, because 10/0 is not 0.

SLC
10D/0D = double.Infinity, not an error. Depending upon the nature of the application, this could be rendered as the infinity symbol (∞) or rendered as an error.
Paul Ruane
Ah! Great Answer! So... you'd throw the error in cases when you'd want to bubble up the Exception to a higher level instead of handling it!
Atømix
+1  A: 

In your own code, I doubt there would be much use. However, if you are writing a library that will be consumed by others then you should use exceptions as the means of communicating errors back to the code consuming your library.

"In the Framework, exceptions are used for both hard errors and logical errors. At first, it can be difficult to embrace exception handling as the means of reporting all functional failures. However, it is important to design all public methods of a framework to report method-failures by throwing an exception."

Krzysztof Cwalina, Designing Reusable Frameworks

Dan Diplo
+2  A: 

If you're writing a BigInteger library, then you absolutely should throw an appropriate DivideByZero exception. If you're writing a shopping-cart library, then...eh, probably not.

I can't, at the moment, think of a good reason to throw a NullReferenceException. If you're create an API with documentation that says "The first parameter to HummingBirdFeeder.OpenSugarWaterDispenser(Dispenser dispenser, int flowRate) is the sugar-water dispenser that you wish to open." And if somebody then comes along and passes a null value to this method, then you should definitely throw an ArgumentNullException.

Letting a NullReferenceException out of your API would just be lazyness, though, because that's wrong and it leaks some of your internals.

EDITED TO ADD:

Now that you changed the question to refer to an ArgumentNullException then the answer is easy: yes, you should definitely throw that kind of exception under these circumstances:

  • You are writing a public method.
  • Getting a null value for the argument is in some way inappropriate (i.e., the method makes no sense without that particular argument).
  • The documentation for the method indicates that null values are not allowed.

In that case, the very first thing your method should do is check for a null value and throw an exception if the condition is violated.

If you are writing a private or internal method, then in most cases you would not need to validate the parameters at runtime in the release build. You can make sure that your own code calls your own code correctly. One thing that helps to create that assurance is to validate the parameters in the debug build by adding assersions:

Debug.Assert(dispenser != null);

This way you can verify that the code is acting correctly and catch any errors earlier without slowing down the released code with a bunch of useless, redundant checks.

Jeffrey L Whitledge
Thanks! Actually, I typed NullReferenceException... but was thinking ArgumentNullException. Thanks! I'm going to correct the question!
Atømix
+1  A: 

Slightly misleading title here, it is not about throwing the (special) DivideByZeroException but rather the question:

Should I use exceptions while validating user input?

This has probably been asked before. My take: No, just use a flow that lets you handle this with error codes or booleans.

However, when validating 'data' in deeper layers of an app, throwing an exception is usually the right thing to do.

Henk Holterman
Thanks for the comment. But, I wanted to know if there were cases for throwing an error that is so obviously easy to check for, so I specifically mentioned that one. The deeper layers concept ( answered by a few people already ) is kind of what I was looking for.
Atømix
A: 

Consider that for doubles, a division by zero will actually result in a value: double.Infinity, double.NegativeInfinity or double.NaN, depending upon whether the numerator is positive, negative or zero, respectively.

It may be that these values are already suitable for your case, if not you will probably want to validate the input, and act accordingly, before you perform the division.

If you are writing an API (such as on a library) and want to provide a contract that disallows a division by zero (say it exposes method that performs some kind of division) then you may want to throw this exception then. Typically though, I would reserve this type of exception as an indicator of a programmatic error.

Paul Ruane
+1  A: 

If you were writing a numerical class of some form and can have expected the code calling your class to have performed the validation then I can see it might useful to throw DivisionByZeroException but in almost any other case it would better to check before the operation and throw and ArgumentException or ArgumentOutOfRange exception as appropriate.

NullReferenceException is one of the reserved exceptions that the framework uses that you should never throw through a public API, along with IndexOutOfRange, AccessViolationException and OutOfMemoryException. See the Framework Design Guidelines book or the Code Analysis warning explanation

Ian G
Thanks. I corrected the question (+1 for alerting me to it). I meant `ArgumentNullException`
Atømix
If you are implementing your own indexer, list, dictionary, hash table what would be wrong with throwing `IndexOutOfRange`
Matthew Whited
Good point Matt
Atømix
@Matthew if you look at the MSDN docs for IndexOutOfRange it says specifically "exception that is thrown when an attempt is made to access an element of an array" (http://msdn.microsoft.com/en-us/library/system.indexoutofrangeexception.aspx). We can't implement our own array (can't inherit from System.Array) so using it would be contrary to the documentation of the exception and so users of your API.
Ian G
Good to see people are scared of using things just because the holy book of MSDN says so. An indexer that isn't found is in essence out of range. And as such makes perfect sense to throw an IndexOutOfRange exception. But feel free to throw ArgumentOutOfRangeException or what ever exception you please.
Matthew Whited
A: 

Never (the user will never send 0 as the denominator) and always (the user will always provide appropriate argument values) are dangerous ideas to include in your code. A very small percentage of us program alone, on code that will never be modified or called by another developer. So, we need to write defensive code. In the case of division by zero, I should not be deciding what the appropriate result should be, that falls back on the caller. Throwing the exception seems like a reasonable way to hand the issue back. While there is expense involved, any infrastructure I add to my code to avoid throwing the exception also adds expense.

cdkMoose
A: 

If you are relying on a framework to do the work (.NET or otherwise), then you should let the framework throw the exception.

This will make it easier for consumers of your methods to handle exceptions that are thrown in a standard way.

In the case for dividing by zero, you are just re-implementing the same logic to throw an exception as in the framework.

Even Mien