When to Use an Assertion and When to Use an Exception

When to use an assertion and when to use an exception

Assertions should be used to check something that should never happen, while an exception should be used to check something that might happen.

For example, a function might divide by 0, so an exception should be used, but an assertion could be used to check that the harddrive suddenly disappears.

An assertion would stop the program from running, but an exception would let the program continue running.

Note that if(group != null) is not an assertion, that is just a conditional.

Exception Vs Assertion

Use assertions for internal logic checks within your code, and normal exceptions for error conditions outside your immediate code's control.

Don't forget that assertions can be turned on and off - if you care about things like argument validation, that should be explicit using exceptions. (You could, however, choose to perform argument validation on private methods using assertions, on the grounds that a violation at that point is due to an internal bug rather than an external error.)

Alternatively it's entire reasonable (IMO) to use exceptions for everything. I personally don't use assertions much at all, but it's a matter of personal preference to some extent. (There can certainly be objective arguments for and against assertions, but it's not sufficiently clear cut to remove preference altogether.)

Assert vs Exceptions

I see two use cases for assertions in production code:

At the beginning of a method you would normaly check if the given parameter are valid. For public methods you would use if statments and exceptions. For private methods you would make the simelar checks using assert. The idea is to avoid redundant checks in produktion while in testing (or when somesting goes wrong) you can just activate assertions to do some double checking.

The other reason to use assertions is to document the assumptions that are used in the following code. Like that some value is considered never to be null here.

Here some example code

public class Exampel {
public publicMethod(final Integer i) {
if (i == null) {
throw new RuntimeException("i should not be null");
}

privateMethod(i):
}

private privateMethod(final Integer i) {
assert i != null;

// do something
}
}

You would not want to check i for null several times. You would just assume that privateMethodis used correctly. You also give anyone that reads your code the hint that passing null to privateMethodis the wrong thing to do.

When to use assert() and when to use try catch?

Try... catch - for exceptional conditions, i.e. conditions which aren't caused by malformed code, but which may just alter the normal control flow by external unpredictable events.

Assertions for catching invalid code, i.e. checking if an invariant is held in the function, checking if an internal method is called with right arguments (for public API you might still want an exception for that), etc.

Those are my basic guidelines, but the conventions vary from situation to situation and from language to language.


When you're in doubt, you can ask yourself: is that specific safety check supposed to still be there in the release code, after we test and finish everything? If you answer "yes, it's still neccessary then", you probably want an exception. Otherwise, you probably want an assertion.

What does the Java assert keyword do, and when should it be used?

Assertions (by way of the assert keyword) were added in Java 1.4. They are used to verify the correctness of an invariant in the code. They should never be triggered in production code, and are indicative of a bug or misuse of a code path. They can be activated at run-time by way of the -ea option on the java command, but are not turned on by default.

An example:

public Foo acquireFoo(int id) {
Foo result = null;
if (id > 50) {
result = fooService.read(id);
} else {
result = new Foo(id);
}
assert result != null;

return result;
}

When to use assertion over exceptions in domain classes

Use exceptions for parameter validation and other checks which verify that the users of you classes use them as intended.

Use assertions for internal consistency checks, i.e. to indicate you screwed up, not the user of your class.

Thus, if users of your class see an assertion failure, they know it is (probably) an internal error in your code, not in their use of your code. On the other hand, if the get parameter validation exception, they know it's their fault.

Why use assert instead of exception throwing?

Assert is only for debugging, and allows you to check invariants in a one-liner. Asserts and similar macros are used ubiquitously in testing frameworks. With exceptions, you really need to care what the rest of your library or program is doing. Asserts are as simple as it gets.

It will crash the program without any ambiguity as to what caused it - your assert caused it. It is easier to go there in a debugger. An exception may be caught and will not stop the program or may cause side-effects such as stack-unwinding from a place where it wouldn't normally occur, calling all the destructors, etc., when you don't really care about that since you're debugging.

With exceptions, you need to declare functions to throw, must enable exceptions in languages like C++, etc.

If you're debugging interactively and not just running test cases in batch mode, and as your example is in Python, I think you'd find a function that starts pdb and stops the program right there more helpful.

Assertion VS Runtime exception

Assertions are usually a development technique that can be switched off in production. That's true in Java, Eiffel, C++, and every language that I know that uses them.

Personally I prefer runtime exceptions to enforce the contract. You can't turn those off.

What's the difference between raise, try, and assert?

Assert:

Used when you want to "stop" the script based on a certain condition and return something to help debug faster:

list_ = ["a","b","x"]
assert "x" in list_, "x is not in the list"
print("passed")
#>> prints passed

list_ = ["a","b","c"]
assert "x" in list_, "x is not in the list"
print("passed")
#>>
Traceback (most recent call last):
File "python", line 2, in <module>
AssertionError: x is not in the list

Raise:

Two reasons where this is useful:

1/ To be used with try and except blocks. Raise an error of your choosing, could be custom like below and doesn't stop the script if you pass or continue the script; or can be predefined errors raise ValueError()

class Custom_error(BaseException):
pass

try:
print("hello")
raise Custom_error
print("world")
except Custom_error:
print("found it not stopping now")

print("im outside")

>> hello
>> found it not stopping now
>> im outside

Noticed it didn't stop? We can stop it using just exit(1) in the except block.

2/ Raise can also be used to re-raise the current error to pass it up the stack to see if something else can handle it.

except SomeError, e:
if not can_handle(e):
raise
someone_take_care_of_it(e)

Try/Except blocks:

Does exactly what you think, tries something if an error comes up you catch it and deal with it however you like. No example since there's one above.



Related Topics



Leave a reply



Submit