1

I'm reading The Pragmatic Programmer and in the section Assertive programming the authors say:

Don’t use assertions in place of real error handling. Assertions check for things that should never happen: you don’t want to be writing code such as the following:

puts(​"Enter 'Y' or 'N': "​)
ans = gets[0] ​# Grab first character of response​
assert((ch == ​'Y'​) || (ch == ​'N'​))    ​# Very bad idea!​

I'm expecting only two values (either Y/N) and if it received some other input, I would want to assert it and throw an error. I want to understand why the assert approach is wrong and what would be a better approach?

Henry Twist
  • 5,666
  • 3
  • 19
  • 44
A Baldino
  • 178
  • 1
  • 11
  • 1
    I agree with their comment, "Don't use in place of real error handling." Basically assertions are normally disabled, so they won't catch errors. Assertions are normally enabled only during test, so that's the only place they might happen. And more recently (i.e., in the last 15 years) I haven't seen assertions used much at all, and I feel they've fallen out of favor, replaced by increasing sophisticated test frameworks. – markspace Mar 25 '21 at 03:03
  • @markspace while i agree other frameworks have taken the place of assertion, i was trying to understand the right use of them compared with exception handling. And yes, i see an important point you made on assertion being turned off by default in production. Thank you. – A Baldino Mar 25 '21 at 03:10
  • Honestly I think the "right use of them" is nowhere. They're an old idea that has been completely superseded. That's just an opinion but I can't think of anything I've seen that contradicts it. – markspace Mar 25 '21 at 03:23

2 Answers2

2

If the user inputs something invalid, you should let them know with an error message or warning. Deliberately causing a crash due to the user's mistake would never be a good idea.

Say you're coding a simple login process. If the user enters an incorrect password, do you tell them it's incorrect or cause a crash without letting them know why?


As it says in the source you provided, assertions should be used for events that should never occur, and most of the time events that your program cannot recover from if they do end up happening. Errors related to user input, networking, sensor data etc. should be handled gracefully.

Also as @markspace mentioned, assertions are quite commonly disabled/can be disabled, so should never be used in place of any type of error handling on the user's end.

Henry Twist
  • 5,666
  • 3
  • 19
  • 44
  • Thanks for your reply. I come from a java & spring experience. If assertion fails, it throws an error that i can catch and handle it appropriately. So in case of your login example, if its fails i handle the exception and do redirect or send appropriate message. One question that came from your reply is, is an assertion failure expected to lead to application failure and stopping of app completely compared with exception handling ? Trying to understand the difference. – A Baldino Mar 25 '21 at 03:06
  • Yes generally an assertion would be expected to cause an application failure. Assertions are generally expected to be used when the application should not continue if the assertion fails. Technically you can (in Java) catch an assertion error like you do an exception but this would be a very strange use case. – Henry Twist Mar 25 '21 at 03:15
  • Also catching errors in that way seems like quite a dirty approach to me, there are usually much more graceful ways to handle errors thrown by your own code. – Henry Twist Mar 25 '21 at 03:16
0

Please review Differences between Exception and Error

asserts are used to validate the program's logic. They throw an AssertionError, indicating there's an error in the code.

To handle user errors, you should throw exceptions, and handle them as appropriate. In case of invalid user input, IllegalArgumentException is reasonable, but you may prefer your own Exception hierarchy. Whether you use checked or unchecked exceptions is up to your preference.

If you want to validate this frequently, you may want to implement a simple validation library:

public static <T> void ensureValue(T value, T... legalValues) {
    if (!Arrays.asList(legalValues).contains(value)) {
        throw new IllegalArgumentException("Invalid value: " + value);
    }
}
ykaganovich
  • 14,736
  • 8
  • 59
  • 96