Error checking

L

Lionel

One thing I have been pondering is where should errors be caught and
checked.

Say I have a JTable and it has rows with a cell for each of the
variables a, b, and c in an instance of the class VariableClass. If a
can only have a value >= 0 I currently only check this when the user
enters the value, the class VariableClass assumes it gets a correct
entry. I have done this quite successfully.

However I'm wondering if just checking user input is enough? Should I
check the values when the instance of VariableClass is instantiated and
when setters are used? Then should I perhaps throw an exception or
handle it some other way?

Thanks

Lionel.
 
C

Chris Smith

Lionel said:
However I'm wondering if just checking user input is enough? Should I
check the values when the instance of VariableClass is instantiated and
when setters are used? Then should I perhaps throw an exception or
handle it some other way?

It's your call.

If you think of your API as "published" then you should definitely check
all inputs to the routine and throw appropriate exceptions if they are
invalid. By published, I mean that you intend to sort of finish it up
and keep it around to be used later, whether by yourself or others. If
you just want to check that an intermediate result is valid, you can use
assertions in a non-published API... but I never have used them,
actually, because it always seems better to just go ahead and throw
exceptions.

On the other hand, there's nothing wrong with just assuming that inputs
are valid for a quick private method that's only used in one or two
classes.
 
L

Lionel

Chris said:
It's your call.

If you think of your API as "published" then you should definitely check
all inputs to the routine and throw appropriate exceptions if they are
invalid. By published, I mean that you intend to sort of finish it up
and keep it around to be used later, whether by yourself or others. If
you just want to check that an intermediate result is valid, you can use
assertions in a non-published API... but I never have used them,
actually, because it always seems better to just go ahead and throw
exceptions.

I didn't know that Java supported assertions, I've got the documentation
open now. That's very interesting and I imagine it is useful if you can
run a model checker on you code.

On the other hand, there's nothing wrong with just assuming that inputs
are valid for a quick private method that's only used in one or two
classes.



I suppose my thoughts are that if I throw exceptions it makes the whole
application a bit tighter and it's more likely to reveal bugs and handle
them better. I'm sure it will make debugging easier too. It also means a
whole load more try-catch blocks so I'm in two minds on the subject.

At least you have given me some satisfaction that I'm not doing things
badly.

Lionel.
 
L

Lew

Lionel said:
Chris Smith wrote:
It's your call.

If ...
you just want to check that an intermediate result is valid, you can use
assertions in a non-published API... but I never have used them,
actually, because it always seems better to just go ahead and throw
exceptions.

On the other hand, there's nothing wrong with just assuming that inputs
are valid for a quick private method that's only used in one or two
classes.

Formally, assertions are used to validate preconditions and postconditions,
and assertion failures in Java by definition "just go ahead and throw an
exception" (actually, an AssertionError). They are appropriate only for a
private method or within a block of code. (BTW, how could one use a private
method in two classes?)

Assertions are used to guarantee provable conditions about an algorithm. It's
worthwhile to read up on them before coding with them. The idea is that an
assertion will never fail.

Protected, package-private and public methods cannot assert about their inputs
because they do not have control over them. Private methods, and intermediate
results, do have control over their preconditions.

It is not always better to throw exceptions. As the name implies, an
exception should be exceptional, and an application should eat exceptions
before they reach the user. How do you like using a program that suddenly
stops with an arcane stack trace?

Exceptions are for APIs, where the caller will handle the exception. Almost
always these should declare checked exceptions, thence the method signature
will require the caller to handle them. Many times it makes more sense to
return a sentinel value rather than throw an exception; for example a Map or
database might return null on a retrieval failure.

For user inputs you should not throw an exception but instead deliver some
reasonable message and re-entry option. A program should handle its entire
domain of inputs reasonably.

- Lew Bloch
 
C

Chris Smith

Lew said:
Formally, assertions are used to validate preconditions and postconditions,
and assertion failures in Java by definition "just go ahead and throw an
exception" (actually, an AssertionError).

Actually, they do so only if assertions are enabled; otherwise, they
don't. This was apparently done to appease the high-performance crowd,
but in my mind, it makes assertions a poor choice for many cases where I
might otherwise use them.
(BTW, how could one use a private
method in two classes?)

Eh, obviously you can't. I added "or two" after thought, later in the
message, and didn't happen to change "private".
It is not always better to throw exceptions. As the name implies, an
exception should be exceptional, and an application should eat exceptions
before they reach the user. How do you like using a program that suddenly
stops with an arcane stack trace?

We're talking about how much validity checking to do in addition to
checking user input. These are all things that should never happen.
That is the context of the discussion. In those cases, I'd rather a
program suddenly stops with a stack trace than continues and gets the
result wrong.

Certainly the occurrence of something that should never happen ought to
be considered "exceptional", unless you subscribe the extremist group
that believes only things like alignment faults and MMU page faults
count as exceptional.
 
C

Chris Smith

Lionel said:
I didn't know that Java supported assertions, I've got the documentation
open now. That's very interesting and I imagine it is useful if you can
run a model checker on you code.

Run a model checker? Unfortunately, there's no static checking of
assertions in Java. Assertions are just a shorthand for (maybe, if
assertions are enabled) throwing an exception (AssertionError) at
runtime is some condition is not true.
I suppose my thoughts are that if I throw exceptions it makes the whole
application a bit tighter and it's more likely to reveal bugs and handle
them better. I'm sure it will make debugging easier too. It also means a
whole load more try-catch blocks so I'm in two minds on the subject.

If we're still talking about situations where you should know that
something is true, then it doesn't mean any try/catch blocks. Throw a
RuntimeException or some subclass, and don't catch it. Let the
application fail and report it.

There is still a tradeoff, though. If you litter your code with
statements like "if (a < 0) throw new RuntimeException();", then it will
quickly begin distracting your readers from important facts about the
code. In fact, I'd suggest that if you can't phrase nearly all of your
constraints on intermediate results as bad parameters to some function,
then you probably need more functions. RuntimeException is sometimes
useful, though, for the default case of a switch and such situations.
At least you have given me some satisfaction that I'm not doing things
badly.

If you're thinking about readability and maintenance, then you aren't
doing things badly.
 
L

Lionel

Chris said:
Run a model checker?

I'm in research mostly for the moment. There is some work on model
checking Java code and I'm sure assertions help model checkers formalise
errors.

If we're still talking about situations where you should know that
something is true, then it doesn't mean any try/catch blocks. Throw a
RuntimeException or some subclass, and don't catch it. Let the
application fail and report it.

I'm with you on the RuntimeException. But what would get reported to the
user if you let it fall through?

There is still a tradeoff, though. If you litter your code with
statements like "if (a < 0) throw new RuntimeException();", then it will
quickly begin distracting your readers from important facts about the
code. In fact, I'd suggest that if you can't phrase nearly all of your
constraints on intermediate results as bad parameters to some function,
then you probably need more functions. RuntimeException is sometimes
useful, though, for the default case of a switch and such situations.

There are only a few setters and constructors that I would need to throw
exceptions for.

If you're thinking about readability and maintenance, then you aren't
doing things badly.

That's what I was thinking.

Thanks

Lionel.
 
O

Oliver Wong

Lionel said:
I'm with you on the RuntimeException. But what would get reported to the
user if you let it fall through?

You could show a blurb about "Please copy and paste this stacktrace and
e-mail it to the developer, along with a description of what you were
doing." Or you could get fancy and ask the user if they want to report the
error, and if so, automatically connect to some central server and upload
the crash report, the way WindowsXP does.

- Oliver
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,266
Messages
2,571,077
Members
48,772
Latest member
Backspace Studios

Latest Threads

Top