Hi,
Everything is in the title: when would you throw an exception
(possibly with some text) at the place of simply making a
System.err.println(some text) and then a System.exit?
It is clear that when an internal error occurs an exception needs to
be thrown. But if some user arguments are directly rejected by your
code (either of the bad types, or in bad quantity, etc.), and that you
know it, do you need to use only exceptions?
For example, when it looks clear to me that
==
try
{
int n = Integer.parseInt(args[0]);
}
catch (NumberFormatException noInteger)
{
System.err.println("Your arg needs to be an int.");
System.exit(1);
}
==
holds, it is less clear if, say, n, is negative when it is assumed to
be positive. Would you throw an exception in this case?
Thanks.
- --
Merciadri Luca
See http://www.student.montefiore.ulg.ac.be/~merciadri/
- --
A rolling stone gathers no moss.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Processed by Mailcrypt 3.5.8 <http://mailcrypt.sourceforge.net/>
iEYEARECAAYFAk2PnCcACgkQM0LLzLt8MhzkOwCeOpRMzV+XGzuvzBQlVnWRKS9Y
nQ4AoJYrJoNGO/WQUskl0L08LafCcDVJ
=8ukC
-----END PGP SIGNATURE-----
>Everything is in the title: when would you throw an exception
>(possibly with some text) at the place of simply making a
>System.err.println(some text) and then a System.exit?
If are writing code that others will use, nearly always you want an
Exception. They might want to try to recover. They might want to give
an error message that is more comprehensible to their users. They
might want to exit. I don't know.
The problem with quietly exiting is you won't get a stack dump giving
you additional information as to why you failed.
Exit should be used for application data/user errors. Program bugs
should die with a stack dump.
--
Roedy Green Canadian Mind Products
http://mindprod.com
There are only two industries that refer to their customers as "users".
~ Edward Tufte
Roedy Green <see_w...@mindprod.com.invalid> writes:
> On Sun, 27 Mar 2011 22:20:55 +0200, Merciadri Luca
> <Luca.Me...@student.ulg.ac.be> wrote, quoted or indirectly quoted
> someone who said :
>
>>Everything is in the title: when would you throw an exception
>>(possibly with some text) at the place of simply making a
>>System.err.println(some text) and then a System.exit?
>
> If are writing code that others will use, nearly always you want an
> Exception. They might want to try to recover. They might want to give
> an error message that is more comprehensible to their users. They
> might want to exit. I don't know.
>
> The problem with quietly exiting is you won't get a stack dump giving
> you additional information as to why you failed.
>
> Exit should be used for application data/user errors. Program bugs
> should die with a stack dump.
Just as in the case where the user gives bad data to the program, for
example, I presume. But consider the case illustrated in my OP. I
there throw an exception because I have no other choice, so that using
System.err for other `bad user inputs' creates inconsistency because
either exceptions OR System.err should thus be used for dealing with
user data input.
- --
Merciadri Luca
See http://www.student.montefiore.ulg.ac.be/~merciadri/
- --
Act today only, tomorrow is too late.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Processed by Mailcrypt 3.5.8 <http://mailcrypt.sourceforge.net/>
iEYEARECAAYFAk2QSYgACgkQM0LLzLt8MhwLYwCgroANz/iaNjuLp4T/Qz8Qk2Kf
TGQAn2rnlRBoBTJ2/OesQTXFNsvhE4CX
=LGkk
-----END PGP SIGNATURE-----
That is presumptuous. No, the program should not die with a stack dump when a
user enters bad data!
Would *you* accept that behavior from someone else's program? What if you had
to reboot your calculator every time you tried to divide by zero?
No! Do not crash a program for bad data!
--
Lew
Honi soit qui mal y pense.
http://upload.wikimedia.org/wikipedia/commons/c/cf/Friz.jpg
A method should normally throw an exception. In general it's
inappropriate for a method to output anything, unless it is explicit
required. It should almost certainly never exit.
It is the responsibility of whatever code invoked the method to handle
the exception. What it does with it is down to the program logic. It may
be that now is the appropriate time to deal with the exception, in which
case it might output an error message, or exit, or both. Or, if it
doesn't know how to deal with the exception it can pass it back up to a
higher authority. Eventually, if nothing elects to handle it, it will be
passed up to the JVM and that will output a stack trace.
>
> It is clear that when an internal error occurs an exception needs to
> be thrown. But if some user arguments are directly rejected by your
> code (either of the bad types, or in bad quantity, etc.), and that you
> know it, do you need to use only exceptions?
There can be no hard and fast rules. Only the logic of your program, and
the current situation within that program, can determine the appropriate
action to be taken.
>
> For example, when it looks clear to me that
> ==
> try
> {
> int n = Integer.parseInt(args[0]);
> }
> catch (NumberFormatException noInteger)
> {
> System.err.println("Your arg needs to be an int.");
> System.exit(1);
> }
> ==
> holds,
This sort of action is really only appropriate in command line argument
parsing, when done right at the start of the main program where you can
fail-fast. But if the parsing is done elsewhere it should fail by
exception, and never exit.
For example, take the Apache Commons CLI class
(http://commons.apache.org/cli/) which parses command lines. If you used
that class to parse the command line passed to your program it would not
be inappropriate for it to exit your program if it detected an error.
Neither should it output messages to System.err, it's up to your program
to determine the appropriate destination for error messages, not a class
library. Compare the methods CommandLine.getOptionObject with
CommandLine.getParsedOptionValue. The former has been deprecated because
it output to System.err. Instead getParsedOptionValue throws an
exception, and returns the message in the exception, so the caller can
determine what to do with it.
> it is less clear if, say, n, is negative when it is assumed to
> be positive. Would you throw an exception in this case?
If the input is in error it probably matters little whether it's because
it's not a number or because it's negative rather than positive. At
least it's not really appropriate for the parser to determine different
courses of action. The decision to throw an exception, or output a
message and exit, depends entirely on where within the overall structure
of your program the parsing is being done, and how your program is
designed to handle faulty user input.
There really cannot be any definitive answer. For example, suppose your
code has already run for an hour, calculating some intermediate results,
and then asks the user for further input to clarify what to do next
based on those results. Would it be appropriate at that time to
completely waste an hour of processing simply because the user input an
incorrect value? If the code is being used as part of a GUI, and the
input comes from a text field, an error message output to System.err
will probably never be seen by the user, and exiting would almost
certainly be inappropriate.
--
Nigel Wade
Nigel Wade <nmw-...@ion.le.ac.uk> writes:
Thanks for this message. This is really well explained and looks
skillful.
In the case that presently concerns me these days (because of the
current project), I'm directly parsing CLI args, and the program takes
no more than 2 secs to launch and quit. As a result, in these
conditions, I find inconsistent to throw an exception when, say, an
argument (which had to be some integer) is something else than an
integer, when I do not throw an exception if this argument does not
fulfill some specific rules such as the one which states that its
value needs to be greater than 0. However, it appears natural to throw
an exception in the case of something which is not an integer, because
Integer.parseInt can directly be embedded in a try block, when the
catch follows.
- --
Merciadri Luca
See http://www.student.montefiore.ulg.ac.be/~merciadri/
- --
All flowers are not in one garden.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Processed by Mailcrypt 3.5.8 <http://mailcrypt.sourceforge.net/>
iEYEARECAAYFAk2Qv4gACgkQM0LLzLt8Mhxz+QCbBhPIlrBiYNpLZc7JTt3dKfQF
OtwAn0DzOavJ7pot00Fvzyp8TUk02sD5
=W3Cx
-----END PGP SIGNATURE-----
So, why *not* throw an exception when the argument is less than zero?
Throwing an exception means the method can't proceed normally for some
reason; I don't see why you *wouldn't* report "unexpected negative
number" as an exception. You need to throw a specific enough exception
that the code that calls your method can distinguish among cases that
matter to it, and provide enough information for the caller to report
something sensible to a user if that's what the caller decides to do.
So:
- NumberFormatException, thrown by ParseInt, makes sense for the "not
really a number" problem, and you can just pass it through.
- You need to figure out an appropriate exception to use for "number not
in the right range". If you want to go whole hog you could define your
own exception that included the value read and the upper/lower bounds
you were looking for (e.g. 1 and Integer.MAX_VALUE), which would be
plenty for a caller to use in producing a fully informative and
localized user message (which you could even provide via your exception
class's getLocalizedMessage method). Or you might find some existing
exception to be good enough.
It's best to use a standard one for this type of exception. At the very
least, inherit from 'RuntimeException' - for this particular mistake I'd use
'IllegalArgumentException' or 'IndexOutOfBoundsException', though the mistake
isn't exactly about an index.
You could also subtype 'IllegalArgumentException' or 'NumberFormatException'
to distinguish the range problem:
public class RangeException extends IllegalArgumentException
{
public RangeException() {}
public RangeException( String s ) { super( s ); }
public RangeException( Throwable cause ) { super( cause ); }
public RangeException( String s, Throwable cause ) { super( s, cause ); }
}
> exception that included the value read and the upper/lower bounds you were
> looking for (e.g. 1 and Integer.MAX_VALUE), which would be plenty for a caller
> to use in producing a fully informative and localized user message (which you
> could even provide via your exception class's getLocalizedMessage method). Or
> you might find some existing exception to be good enough.
>
--
Lew
overhead at an apartment where the super was evicting a tenant:
super: cause afraid your lease took acts - be y'all who do' shuts out, Mary
Poppins.
Thanks for pointing that out -- I'd certainly have looked for something
to subclass. I'd want to think about what parent class to use, though.
Neither of those seems quite right for an incorrect user input, if
your method is popping up a dialog box itself. If you're talking about
a string passed to your method that happened to come from user input --
well, there's no way for your method to know that, so it's an illegal
argument (there's nothing wrong with the format).
Merciadri Luca <Luca.Me...@student.ulg.ac.be> writes:
> Roedy Green <see_w...@mindprod.com.invalid> writes:
>
>> On Sun, 27 Mar 2011 22:20:55 +0200, Merciadri Luca
>> <Luca.Me...@student.ulg.ac.be> wrote, quoted or indirectly quoted
>> someone who said :
>>
>>>Everything is in the title: when would you throw an exception
>>>(possibly with some text) at the place of simply making a
>>>System.err.println(some text) and then a System.exit?
>>
>> If are writing code that others will use, nearly always you want an
>> Exception. They might want to try to recover. They might want to give
>> an error message that is more comprehensible to their users. They
>> might want to exit. I don't know.
>>
>> The problem with quietly exiting is you won't get a stack dump giving
>> you additional information as to why you failed.
>>
>> Exit should be used for application data/user errors. Program bugs
>> should die with a stack dump.
> Just as in the case where the user gives bad data to the program, for
> example, I presume. But consider the case illustrated in my OP. I
> there throw an exception because I have no other choice, so that using
> System.err for other `bad user inputs' creates inconsistency because
> either exceptions OR System.err should thus be used for dealing with
> user data input.
Thanks for all these interesting answers.
- --
Merciadri Luca
See http://www.student.montefiore.ulg.ac.be/~merciadri/
- --
Better is the enemy of good.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Processed by Mailcrypt 3.5.8 <http://mailcrypt.sourceforge.net/>
iEYEARECAAYFAk2SX3AACgkQM0LLzLt8MhxwjQCfVIuHKOy7oPKRmT7dqlXuxua/
SlcAniecTegRwjKaNJ35hHB7BdJlD24J
=9U5J
-----END PGP SIGNATURE-----
Sorry, I can't agree that using exceptions to process user input is a good idea.
Runtime exceptions are to catch and repair programming errors, not user input.
There is no such thing as "bad" input. Therefore no input should ever thrown
an exception - not from the business perspective. Yes, exceptions happen low
down in the code - presumably only checked exceptions, but that's another
debate. But the code that invokes such a method, especially because the
checked exception requires it, will catch and deal with the exception.
As touted in /Effective Java/ by Joshua Bloch, Chapter 9, [1] you should favor
prevention of exceptions over trapping them. To process input, sometimes you
have to cheat and use an exception, but by and large you want to validate
input prior to submitting it to business logic. The cheat with an exception
is a highly-localized idiom to substitute for a more proper conditional,
wrapped to pretend to higher layers that it really was a conditional, used
only at pressing need.
Therefore, no exception, much less the ones I mentioned, is at all "right for
an incorrect user input". Runtime exceptions are for things like incorrect
arguments to methods or improper data fed to range-bound methods (a kind of
incorrect argument). So I figure that in the great majority of applications
I'd use 'IllegalArgumentException' for such a thing.
[1]
<http://java.sun.com/docs/books/effective/toc.html>
Item 57: Use exceptions only for exceptional conditions
Item 58: Use checked exceptions for recoverable conditions and runtime
exceptions for programming errors
Item 60: Favor the use of standard exceptions
*Item 62: Document all exceptions thrown by each method*
*Item 65: Don't ignore exceptions*
There is a bad user input exception but the point is that it's a
program problem by the time it becomes an exception.
If your program accepts the value of 12 from user input where it
expects a value no greater than 10, it's already gotten past the user
input program with incorrect or incomplete validation.
I would think printing (err.println) should only be for debugging, not
necessary for live programs.
Your last point is an interesting question. Don't ignore exceptions?
What does this mean?
Is a try block necessary to catch an exception or only if failure is
an option?
Does the catch block normally have code you could try if the code in
the try block fails?
If all you're going to do with the error is throw it out / inform the
calling program, could you should you leave out try and just add
"throws Exception" to the method declarations?
I agree with the point so I won't quibble with the phrasing.
> If your program accepts the value of 12 from user input where it
> expects a value no greater than 10, it's already gotten past the user
> input program with incorrect or incomplete validation.
Which is not an input problem.
> I would think printing (err.println) should only be for debugging, not
> necessary for live programs.
That would be entirely up to the specifications for the "live" program.
System.err.println() is not a good choice for debugging. It's not a terrible
choice for probing development alternatives, but it's still infelicitous. So
only use it where the application requirements call for it.
As for what's good for debugging, when debugging is called for, nothing beats
a debugger. When it is not called for, you leverage the tools available to
the production environment, namely logs. Bear in mind when you write logging
code that its purpose is to support operations, and we developers ride on
those coattails. Logging should not be designed selfishly for a programmer's
convenience.
> Your last point is an interesting question. Don't ignore exceptions?
> What does this mean?
That wasn't /my/ point. That was a chapter ("Item") title from /Effective
Java/ by Joshua Bloch, 2nd ed. Buy it. Study it.
Ignoring exceptions means exactly what the words denote: not paying attention
to them.
There are two kinds of exceptions (by which I mean improper subtypes of
'Exception'): runtime, or unchecked exceptions, and checked exceptions.
One way to ignore runtime exceptions is to completely ignore them and allow
them free rein to crash your app:
public void foo( String sometxt )
{
System.out.println( "Input length "+ sometxt.length()
+" value\n\""+ sometxt +'"';
}
Oops. This just lets the runtime exception percolate up out of the method to
damage the caller.
With checked exceptions you can do the same thing by declaring the method to
throw the exception. This forces the caller to deal with it, though at least
you're warning it that it has to. But unless the method generates that
exception itself, it's usually cheating to let it up out of the method.
The other way to ignore exceptions, applicable to checked exceptions usually
but it works for runtime exceptions also, is to catch the exception, then
ignore it.
public void foo( String sometxt )
{
BufferedReader fr = null;
try
{
BufferedReader fr = new BufferedReader( new FileReader( sometxt ));
for ( String line; (line = fr.readLine()) != null; )
{
System.out.println( line );
}
}
catch ( IOException ioe ) {}
finally
{
if ( fr != null )
{
try
{
fr.close();
}
catch ( IOException ioe ) {}
}
}
There is a lot of ignorance in that example.
> Is a try block necessary to catch an exception or only if failure is
> an option?
I don't understand the question.
A 'catch' block is necessary to catch an exception. You must have a 'try'
block to have a 'catch' block. What do you mean, "if failure is an option"?
> Does the catch block normally have code you could try if the code in
> the try block fails?
No.
> If all you're going to do with the error is throw it out / inform the
Those are two different things.
> calling program, could you should you leave out try and just add
It's not a calling program, it's a calling expression inside a calling method
in the same program.
> "throws Exception" to the method declarations?
No. You can, but it would be bad.
When you declare a checked exception, you are telling the callers of that
method to deal with it. Whom are you telling to deal with the exception with
the strategy you describe? What are they supposed to do with it? Why didn't
the method you defined deal with it?
Why do you seek to avoid dealing with exceptions? The whole point of Mr.
Bloch's advice not to ignore exceptions is NOT TO IGNORE EXCEPTIONS.
--
Lew
Second declaration is a typo. Strike that. Sorry.
Uncompiled code, obviously.
--
Lew
What runtime exception? You didn't catch or throw any exceptions
there. Eclipse doesn't have any warnings or errors on that block,
other than the syntax error for the missing ).
Failure is an option means "try this, and if that doesn't work I have
something else you could try".
> > Does the catch block normally have code you could try if the code in
> > the try block fails?
>
> No.
>
> > If all you're going to do with the error is throw it out / inform the
>
> Those are two different things.
>
> > calling program, could you should you leave out try and just add
>
> It's not a calling program, it's a calling expression inside a calling method
> in the same program.
>
> > "throws Exception" to the method declarations?
>
> No. You can, but it would be bad.
>
> When you declare a checked exception, you are telling the callers of that
> method to deal with it. Whom are you telling to deal with the exception with
> the strategy you describe? What are they supposed to do with it? Why didn't
> the method you defined deal with it?
>
> Why do you seek to avoid dealing with exceptions? The whole point of Mr.
> Bloch's advice not to ignore exceptions is NOT TO IGNORE EXCEPTIONS.
>
> --
> Lew
So, if we don't ignore an Exception, what do we do with it?
For example,
public void foo(String fileName)
{
File myFile = new File(fileName);
myFile.createNewFile();
}
We get an error "Unhandled Exception type IOException".
We can just modify the constructor,
public void foo(String fileName) throws Exception
(or IOException if we import the specific Exception)
If I try it to catch, then what?
public void foo(String fileName) throws Exception
{
try {
File myFile = new File(fileName);
myFile.createNewFile();
}
catch (Exception e)
{
throw e;
}
}
If there's no alternative (if try block fails we have other code we
could try), then the only point to this would be if we want to throw
out a custom message?
There's a potential NPE which will be thrown if the caller passes in a
null String.
> You didn't catch or throw any exceptions
> there.
No, none were caught, but an NPE may be thrown.
> Eclipse doesn't have any warnings or errors on that block,
> other than the syntax error for the missing ).
>
It won't have. NPE is a RuntimeException so doesn't need to be declared,
or caught. It will, however, crash your program if it occurs and you
don't catch it.
--
Nigel Wade
Interesting you can crash that simple program by passing in null
instead of a String and Eclipse doesn't mention it.
So should every such error be thrown or trapped? It would seem such
error should be tracked down in the object where this method is
called, and trapping them all would be a real nuisance.
public void foo( String sometxt )
{
if (sometxt == null) {
throw new RuntimeException("That's a null not a String!");
}
System.out.println( "Input length "+ sometxt.length()
+" value\n\""+ sometxt +'"');
}
Which of these makes more sense?
public void foo(String fileName) throws Exception
{
try {
File myFile = new File(fileName);
myFile.createNewFile();
}
catch (Exception e)
{
throw e;
}
}
public int foo(String fileName)
{
int returnValue = 0;
try {
File myFile = new File(fileName);
myFile.createNewFile();
}
catch (Exception e)
{
returnValue = 1;
}
return returnValue;
}
Aside from tossing out numbers, the alternative to throwing the errors
would seem to be tracking down every possible reason for the error and
passing out..more numbers, or message strings?
NullPointerException. And failure to catch or prevent the exception is
exactly the mistake illustrated, so that was intentional.
> there. Eclipse doesn't have any warnings or errors on that block,
> other than the syntax error for the missing ).
Oops. Thanks for pointing out the parenthesis mistake.
Did you know that Eclipse's warnings are configurable? Turn on the null
pointer warnings.
Eric wrote:
>>> Is a try block necessary to catch an exception or only if failure is
>>> an option?
>> Lew wrote:
>> I don't understand the question.
>>
>> A 'catch' block is necessary to catch an exception. You must have a 'try'
>> block to have a 'catch' block. What do you mean, "if failure is an option"?
> Failure is an option means "try this, and if that doesn't work I have
> something else you could try".
Oh, right. Well, a catch block is a small part of the mechanism to restore
sanity to the program so that higher-level logic can do that.
[snip]
> So, if we don't ignore an Exception, what do we do with it?
Catch it, log it, and restore the program to a sane state. Sometimes that
means rethrowing the exception, but very rarely. More common is to recast
into an application catch-all exception. More common, or better practice in
more situations, is to provide an alternate return from the operation to
signal to the caller that there was a problem - that's where a buried
exception can be rethrown sometimes. It's a matter of art.
Checked exceptions should be converted to a non-exceptional situation and the
method gracefully exited.
Runtime exceptions are more serious, representing programmer error, and might
require abandonment of the operation or the program altogether, again, gracefully.
At the lowest level, an exception usually should be converted to a
non-exceptional condition after logging. Logging is vital.
Then a quick graceful exit from the low level, with a signal (like a bad
return value) to the caller, which gracefully does what you suggested earlier,
that is, create an alternate path for the operation or user or whatever.
> If there's no alternative (if try block fails we have other code we
> could try), then the only point to this would be if we want to throw
> out a custom message?
You don't throw messages, you throw exceptions.
At the low level you usually do not emit messages, but return conditions to
higher-level code. You do not put much into 'catch' blocks at all - log,
clean up, get out, fast.
The higher level makes sense of that for either business logic or user
interaction.
That's not Eclipse's fault. You failed to tell it to report null pointer
problems.
> So should every such error be thrown or trapped? It would seem such
Neither. It should be prevented.
> error should be tracked down in the object where this method is
> called, and trapping them all would be a real nuisance.
> public void foo( String sometxt )
> {
> if (sometxt == null) {
> throw new RuntimeException("That's a null not a String!");
That achieves exactly nothing. NPE already is a RuntimeException. Instead of
throwing a stone through the window you're throwing a baseball. Either way
you have broken glass.
> }
> System.out.println( "Input length "+ sometxt.length()
> +" value\n\""+ sometxt +'"');
> }
>
> Which of these makes more sense?
> public void foo(String fileName) throws Exception
> {
> try {
> File myFile = new File(fileName);
> myFile.createNewFile();
> }
> catch (Exception e)
> {
> throw e;
> }
> }
>
> public int foo(String fileName)
> {
> int returnValue = 0;
> try {
> File myFile = new File(fileName);
> myFile.createNewFile();
> }
> catch (Exception e)
> {
> returnValue = 1;
> }
> return returnValue;
> }
>
> Aside from tossing out numbers, the alternative to throwing the errors
> would seem to be tracking down every possible reason for the error and
> passing out..more numbers, or message strings?
YES! You absolutely MUST track down EVERY possible reason for error and
prevent it. THAT'S PROGRAMMING!
Why would you ever do otherwise? Do you actually want to leave possibility
for error in your program? Really? Why?
Again, don't catch exceptions, prevent them. Do you recall that I posted
upthread:
<http://java.sun.com/docs/books/effective/toc.html>
Item 57: Use exceptions only for exceptional conditions
Item 58: Use checked exceptions for recoverable conditions and runtime
exceptions for programming errors
Item 60: Favor the use of standard exceptions
*Item 62: Document all exceptions thrown by each method*
*Item 65: Don't ignore exceptions*
Buy that book and study it.
public void foo( String sometxt )
{
System.out.println( "Input length "+
(sometxt == null? 0 : sometxt.length())
+" value\n\""+ sometxt +'"' );
}
--
Lew
That sounds like an exception which should never happen. Do you
program for every possible exceptions or just the rational ones?
I want the program to crash if they pass in a null String. That means
the object which called that method is invalid.
If you design a truck for a dog catcher who should only ever have dogs
in the truck, do you need a warning sign "loading any elephants in
this truck will break it"?
>
> > there. Eclipse doesn't have any warnings or errors on that block,
> > other than the syntax error for the missing ).
>
> Oops. Thanks for pointing out the parenthesis mistake.
>
> Did you know that Eclipse's warnings are configurable? Turn on the null
> pointer warnings.
I'm not seeing any warnings on that method. I have errors configured:
Null pointer access = Warning
Potential null pointer access = Warning
>
> Eric wrote:
> >>> Is a try block necessary to catch an exception or only if failure is
> >>> an option?
> >> Lew wrote:
> >> I don't understand the question.
>
> >> A 'catch' block is necessary to catch an exception. You must have a 'try'
> >> block to have a 'catch' block. What do you mean, "if failure is an option"?
> > Failure is an option means "try this, and if that doesn't work I have
> > something else you could try".
>
> Oh, right. Well, a catch block is a small part of the mechanism to restore
> sanity to the program so that higher-level logic can do that.
>
Are you suggesting Oracle is wrong? I've gotten a number of
Exceptions thrown from their object methods. Someone aught to tell
them to start passing out error codes instead.
> [snip]
>
> > So, if we don't ignore an Exception, what do we do with it?
>
> Catch it, log it, and restore the program to a sane state. Sometimes that
> means rethrowing the exception, but very rarely. More common is to recast
> into an application catch-all exception. More common, or better practice in
> more situations, is to provide an alternate return from the operation to
> signal to the caller that there was a problem - that's where a buried
> exception can be rethrown sometimes. It's a matter of art.
Now you're sending mixed messages. Catch the error just to rethrow
it, recast it, or set a variable and hope the object which called the
method bothered to check the return code?
try {
testcode();
}
catch (Exception e) {
throw new MyAppException(e);
}
It sounds like your quote "Favor the use of standard exceptions" is
contrary to your message "recast into an application catch-all
exception".
"That achieves exactly nothing. NPE already is a RuntimeException."
means you're suggesting don't crash for null Strings just log it and
return out quietly hoping whoever called your method knows or doesn't
care?
"You absolutely MUST track down EVERY possible reason for error and
prevent it." is the responsibility of every object, or every object
which calls the object? Are you just wasting time putting "do not
drink" labels on a bottle of motor oil and "do not plug with a potato"
on the tailpipe?
>
> Checked exceptions should be converted to a non-exceptional situation and the
> method gracefully exited.
>
> Runtime exceptions are more serious, representing programmer error, and might
> require abandonment of the operation or the program altogether, again, gracefully.
>
> At the lowest level, an exception usually should be converted to a
> non-exceptional condition after logging. Logging is vital.
>
> Then a quick graceful exit from the low level, with a signal (like a bad
> return value) to the caller, which gracefully does what you suggested earlier,
> that is, create an alternate path for the operation or user or whatever.
>
To what extent? If every object checked for every possible error and
passed out a number or string to identify any errors, there would be
no need for a throw verb.
I tend to expect if you're writing a method in an API to be used by
other objects, those objects should check for any errors they might
encounter.
If I'm writing a File.createNewFile method, I shouldn't have to have a
long conditional statement to return the value of any possible error
(file name is incorrect, path is invalid, drive is unavailable, object
doesn't have permission to write, file already exists, file name
variable is null, etc).
Then if you pass out a value instead of crashing and you have another
method which requires that value as input you have to validate it
again even though the object calling your methods just got the value
from you so they already know it's valid.
I tend to think you can just go overboard on validation especially on
low level methods. Passing out a string to clarify the error instead
of throwing the error should be most useful on the user level, if
they're running it from a command line.
> > If there's no alternative (if try block fails we have other code we
> > could try), then the only point to this would be if we want to throw
> > out a custom message?
>
> You don't throw messages, you throw exceptions.
Semantics. As my previous example:
throw new RuntimeException("That's a null not a String!");
You're throwing a custom message as an exception.
The alternative is returning a message if you have a string or an
object containing a string in the normal return value, and assume
anyone calling the method is checking the return string if they need
to.
>
> At the low level you usually do not emit messages, but return conditions to
> higher-level code. You do not put much into 'catch' blocks at all - log,
> clean up, get out, fast.
>
> The higher level makes sense of that for either business logic or user
> interaction.
>
> --
> Lew
> Honi soit qui mal y pense.http://upload.wikimedia.org/wikipedia/commons/c/cf/Friz.jpg
Do you have an example of that "log, clean up, get out"? If it's
doing the same thing for every error why have a try catch in the first
place, they should have a method to tell it what to do on errors for
the entire object.
Why did you ask this question a second time? Did you read my answer the first
time? For reference, again!, it was:
> YES! You absolutely MUST track down EVERY possible reason for error and prevent it.
> THAT'S PROGRAMMING!
> Why would you ever do otherwise? Do you actually want to leave possibility for error in your program?
> Really? Why?
> Again, don't catch exceptions, prevent them. Do you recall that I posted upthread:
>
> <http://java.sun.com/docs/books/effective/toc.html>
What part of that answer was not clear?
> I want the program to crash if they pass in a null String. That means
NO!
That is a VERY STUPID idea.
Instead, have the program exit on errors. Even better, have it handle the
exception.
Don't do stupid things. Do smart things.
> the object which called that method is invalid.
> If you design a truck for a dog catcher who should only ever have dogs
> in the truck, do you need a warning sign "loading any elephants in
> this truck will break it"?
Invalid analogy. Just follow the advice. Did you buy and read /Effective
Java/ yet? If not, why are you still posting questions here?
Why should we give you more advice when you're not listening to the answers,
and we can't tell that you're following the advice?
> I'm not seeing any warnings on that method. I have errors configured:
> Null pointer access = Warning
> Potential null pointer access = Warning
That method was not presented in an SSCCE. Would you please post your
complete version of that example?
Your statement indicates nothing.
> Are you suggesting Oracle is wrong? I've gotten a number of
> Exceptions thrown from their object methods. Someone aught [sic] to tell
> them to start passing out error codes instead.
Sorry?
Those are library calls, not applications. Did you read /Effective Java/ yet?
Just be quiet and learn. You don't know enough to argue and be snarky like
that yet.
> It sounds like your quote "Favor the use of standard exceptions" is
> contrary to your message "recast into an application catch-all
> exception".
I was laying out the different options. Some are better than others. The art
of programming involves knowing the risks and advantages, limitations and
powers of each approach. STUDY THE RECOMMENDED MATERIAL BEFORE POSTING.
It'll save you much embarrassment.
> To what extent? If every object checked for every possible error and
YES!
You failed to answer my questions, yet you keep asking more. FOUL!
HANDLE *ALL* ERRORS!
What part of that answer was unclear before?
Did you study /Effective Java/ yet?
>> You don't throw messages, you throw exceptions.
> Semantics. As my previous example:
Semantics are important. Why do you pretend that they are not?
> throw new RuntimeException("That's a null not a String!");
> You're throwing a custom message as an exception.
No, you are not.
You are throwing an exception that contains a string. You are not throwing a
message, in Java terms. Yes, O-O defines all interactions as messages, so in
a sense you are throwing a message, but that is not the terminology.
You pretend to want to learn, but you don't follow the recommendations, you
don't answer questions, you argue without knowledge, and you decline to use
the correct terminology. If you are already such an expert, why are you
asking for information?
> The alternative is returning a message if you have a string or an
> object containing a string in the normal return value, and assume
> anyone calling the method is checking the return string if they need
> to.
That is one alternative. Why do you think it's the only one?
Stop arguing from ignorance.
Answer questions, follow advice, READ THE BOOK.
> > YES! You absolutely MUST track down EVERY possible reason for error and prevent it.
> > THAT'S PROGRAMMING!
> > Why would you ever do otherwise? Do you actually want to leave possibility for error in your program?
> > Really? Why?
> > Again, don't catch exceptions, prevent them. Do you recall that I posted upthread:
>
> > <http://java.sun.com/docs/books/effective/toc.html>
>
> What part of that answer was not clear?
>
The part where you said all possible errors should be caught and every
method should exit normally passing out values for every possible
error not throwing anything, then you say it's good to throw errors
because if it were not good practice then the Java API would not do
it, the java.io.File.read() would not crash if the file were
unavailable or the program didn't have access to it, it would exit
gracefully passing out a value to let your program know exactly what
the problem is.
> > I want the program to crash if they pass in a null String. That means
>
> NO!
>
> That is a VERY STUPID idea.
>
> Instead, have the program exit on errors. Even better, have it handle the
> exception.
>
That sounds like good practice for an end user application program.
I'm writing a program which will only be called by other programs,
where it should be safe to assume the input is already valid or else
the calling program/object is incorrect. If we pass in a String which
should always be a String why waste time checking if it's a null?
> Don't do stupid things. Do smart things.
>
Writing redundant code which has a class with a method to be used by
other objects and tells what values to pass in then validates those
values which should already be valid doesn't seem so smart.
> > the object which called that method is invalid.
> > If you design a truck for a dog catcher who should only ever have dogs
> > in the truck, do you need a warning sign "loading any elephants in
> > this truck will break it"?
>
> Invalid analogy. Just follow the advice. Did you buy and read /Effective
> Java/ yet? If not, why are you still posting questions here?
>
Where do I get a free copy of that book? I don't have money for
books.
> Why should we give you more advice when you're not listening to the answers,
> and we can't tell that you're following the advice?
>
I am trying to listen but we are not communicating. Either you're
writing something wrong or I'm reading it wrong. I don't see any
straight answer to my question.
> > I'm not seeing any warnings on that method. I have errors configured:
> > Null pointer access = Warning
> > Potential null pointer access = Warning
>
> That method was not presented in an SSCCE. Would you please post your
> complete version of that example?
>
What was not SSCCE? I just said Eclipse returns no error on your
method which you claim should get the NPE.
>> public void foo( String sometxt )
>> {
>> System.out.println( "Input length "+ sometxt.length()
>> +" value\n\""+ sometxt +'"');
>> }
> Your statement indicates nothing.
>
> > Are you suggesting Oracle is wrong? I've gotten a number of
> > Exceptions thrown from their object methods. Someone aught [sic] to tell
> > them to start passing out error codes instead.
>
> Sorry?
>
> Those are library calls, not applications. Did you read /Effective Java/ yet?
>
Now the throw/throws verbs are not to be used outside of Oracle's
code?
> Just be quiet and learn. You don't know enough to argue and be snarky like
> that yet.
>
I am trying to learn. I apologize if that sounds "snarky" when I ask
a question and get a response which appears confusing or conflicting
and express some of my frustration in an attempt to clarify.
> > It sounds like your quote "Favor the use of standard exceptions" is
> > contrary to your message "recast into an application catch-all
> > exception".
>
> I was laying out the different options. Some are better than others. The art
> of programming involves knowing the risks and advantages, limitations and
> powers of each approach. STUDY THE RECOMMENDED MATERIAL BEFORE POSTING.
> It'll save you much embarrassment.
>
Am I understanding correctly yet, you're saying Java lets you do a lot
of things you shouldn't do, and provides methods which don't catch
errors so you can repeatedly figure out what those errors might be and
catch them yourself every time you use the methods, and the common
practice of throwing errors as used by major open source collaboration
projects is incorrect?
http://docjar.com/docs/api/org/apache/fop/apps/FOPException.html
So to the original question "When to throw exceptions and when to use
System.err?" your answer is "never, errors on any level should be
passed values on the return statement".
You may be the most knowledgeable Java programmer in the world but
writing about it with intent to teach is pointless if you can't make a
student understand, and the forum is pointless if every question is
answered with "don't bother asking, go buy a book and read until you
figure it out yourself".
Have you tried your local library?
--
Beware of bugs in the above code; I have only proved it correct, not
tried it. -- Donald E. Knuth
There isn't one.
> The part where you said all possible errors should be caught and every
> method should exit normally passing out values for every possible
> error not throwing anything, then you say it's good to throw errors
> because if it were not good practice then the Java API would not do
> it, the java.io.File.read() would not crash if the file were
> unavailable or the program didn't have access to it, it would exit
> gracefully passing out a value to let your program know exactly what
> the problem is.
OK, please allow me to clarify, and correct any erroneous comment I made.
One can throw an exception from a method, of course. I didn't say that was
bad. I did say one should not let an exception crash a *program*.
To wit:
> Catch it, log it, and restore the program to a sane state.
> Sometimes that means rethrowing the exception, but very rarely. More common
> is to recast into an application catch-all exception. More common, or better
> practice in more situations, is to provide an alternate return from the
> operation to signal to the caller that there was a problem - that's where a
> buried exception can be rethrown sometimes. It's a matter of art.
Note:
- "restore the *program* to a sane state" - not the method
- I did endorse throwing exceptions from methods
- I described several options
- I made no absolute statements other than EVERY exception must be handled -
again, I'm not saying don't rethrow or wrap-and-throw, but then /that/
exception must be handled so that the *program* gets unexceptional.
Is that clearer?