Exception vs Assert?

49,251

Solution 1

My rule of thumb:

Exceptions are used for run-time error conditions (IO errors, out of memory, can't get a database connection, etc.).

Assertions are used for coding errors (this method doesn't accept nulls, and the developer passed one anyway).

For libraries with public classes, throw exceptions on the public methods (because it makes sense to do so). Assertions are used to catch YOUR mistakes, not theirs.

EDIT: This may not be entirely clear, due to the null value example. My point is that you use assertions (as others have pointed out) for conditions that should NEVER happen, for conditions that should NEVER make it into production code. These conditions absolutely must fail during unit testing or QA testing.

Solution 2

You use exceptions for exceptional situations. For example an out of memory situation or a network failure.

You use assert to ascertain that a cetain precondition is met. For example a pointer is not NULL or an integer is within a certain range.

Solution 3

I use asserts for things that should never happen, yet do. The sort of thing that when it happens, the developer needs to revisit incorrect assumptions.

I use exceptions for everything else.

In reusable code, I prefer an exception because it gives the caller a choice of handling or not handling the problem. Just try catching and handling an assert!

Solution 4

Assert is a means to verify that the program is in a possible state. If a function returns -1 when it should only return positive integers, and you have an assert that verifies that, your program should stop because it puts your program in a dangerous state.

Solution 5

As a general rule, I throw exceptions from:

  1. public functions of a package to catch programming errors.
  2. internal functions to report system errors or pass-through sub-system errors.

where I use asserts only internally to catch implementation mistakes.

Share:
49,251
Admin
Author by

Admin

Updated on March 25, 2021

Comments

  • Admin
    Admin about 3 years

    Possible Duplicate:
    design by contract tests by assert or by exception?

    Is there a rule of thumb to follow when deciding to use exceptions instead of asserts (or vice versa). Right now I do only throw if it's something I think will happen during runtime on the user side (like a socket or file error). Almost everything else I use asserts.

    Also, if I were to throw an assert, what is a nice standard object to throw? If I recall correctly there is std::logic_error, but is that not a good object to throw? What would I throw for a missing file or unexpected input (such as from the command line instead of a frontend app)?

  • Argalatyr
    Argalatyr over 15 years
    The parallelism of "assert" and "ascertain" does not work. To "assert" is to declare positively, whereas "ascertain" is to learn. Thus, assert presupposes "true", whereas ascertain suggests no particular bias. It's not a terrible mnemonic, but the suggested etymology is flawed.
  • hachu
    hachu over 15 years
    Agree with Argalatyr. To assert is "to insist upon", "to declare boldly" or similar. To ascertain is "To discover with certainty, as through examination or experimentation", for which "discover" is a synonym.
  • JW.
    JW. over 15 years
    Also, the "exceptions for exceptional situations" rule could use clarification. Why is a network failure exceptional but not a null pointer?
  • Maxpm
    Maxpm about 12 years
    Could you clarify why public library-methods should throw exceptions? I don't see how one could possibly recover from an illegal argument or bad object state.
  • hachu
    hachu about 12 years
    Certainly. If you're writing the public library method, and someone passes YOU the illegal argument, YOU throw. YOU can't recover from that. Presumably, someone is consuming your library. It's their job to correct the defect. You're absolutely correct: You can't recover from it. Make your caller do it.
  • Maxpm
    Maxpm about 12 years
    How is the caller meant to recover? If a developer uses my library incorrectly, it is a coding error and it should be neither recovered from, nor present in production.
  • hachu
    hachu about 12 years
    But that's the point. He recovers by fixing the defect before it ever reaches production.
  • Maxpm
    Maxpm about 12 years
    But that's him manually rectifying his error, not the program working around it by design. Besides, isn't that exactly what assertions are for, anyway? Finding and fixing defects before they ever reach production?
  • hachu
    hachu about 12 years
    The problem is that an assertion is removed from the release version of your compiled assembly. You can't use it if you're compiling a release build. You must throw.
  • underscore_d
    underscore_d over 5 years
    It's very odd that in a Q on exceptions vs. assertions, you never mentioned the former at all. But re what you said about assertions: What is a "possible state"? As assertions only run in debug mode, they should only be used in dev to catch bugs that should never have been written. Once a program is in the wild, it should be free of bugs (hopelessly utopian, I know, but humour me) and can be run in release mode, so assertions will not catch anything. But errors can result from users doing wacky things, including permutations of input we never thought "possible"... hence the need for exceptions
  • plexando
    plexando about 4 years
    "Exceptions are used for run-time error conditions... Assertions are used for coding errors..." Not entirely true. Exceptions can (and possibly should) be used for coding errors as well: cf. std::logic_error and its derived classes.