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 privateMethod
is used correctly. You also give anyone that reads your code the hint that passing null to privateMethod
is 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
Specific Difference Between Bufferedreader and Filereader
How to Loop Over a Class Attributes in Java
Creating an Animated 4X4 Grid in Java
Closing Bufferedreader and System.In
Why Does This Gridbaglayout Not Appear as Planned
Which Part of Throwing an Exception Is Expensive
JSON Consumer of Polymorphic Objects
What Is the Optimal Capacity and Load Factor for a Fixed-Size Hashmap
How to Convert Set<String> to String[]
User Authentication on a Jersey Rest Service
Stop Scheduled Timer When Shutdown Tomcat
Jtable Getselectedrow Does Not Return the Selected Row Index
How to Decode a String Encoded with Openssl Aes-128-Cbc Using Java
Eclipse Will Not Open Due to Environment Variables