Path: csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!news.albasani.net!eternal-september.org!feeder.eternal-september.org!.POSTED!not-for-mail From: Eric Sosman Newsgroups: comp.lang.java.help Subject: Re: Some same exceptions used in a given file Date: Sat, 23 Apr 2011 18:31:03 -0400 Organization: A noiseless patient Spider Lines: 135 Message-ID: References: <87r58s28w3.fsf@merciadriluca-station.MERCIADRILUCA> <871v0smxvr.fsf@merciadriluca-station.MERCIADRILUCA> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Injection-Date: Sat, 23 Apr 2011 22:31:37 +0000 (UTC) Injection-Info: mx03.eternal-september.org; posting-host="KiwfXDyOjqGhZBXcfNnZBg"; logging-data="1238"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/tcgFkqDLxaapo7Rcjh/k4" User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.15) Gecko/20110303 Thunderbird/3.1.9 In-Reply-To: <871v0smxvr.fsf@merciadriluca-station.MERCIADRILUCA> Cancel-Lock: sha1:V49CddYebG+IUbRcSU3lJei1dNk= Xref: x330-a1.tempe.blueboxinc.net comp.lang.java.help:625 On 4/23/2011 6:00 PM, Merciadri Luca wrote: > Eric Sosman writes: > >> On 4/23/2011 1:08 PM, Merciadri Luca wrote: >>> In some of my code files, I've got the following catch block >>> >>> == >>> catch (IOException cantOpenFile) >>> { >>> System.err.println("Can't open " + inputFilename + "."); >>> System.exit(1); >>> } >>> == >>> more than once, but at different places in the file. Is it possible to >>> define this somewhere so that I can directly catch the exception with >>> the two given commands? (Just as one would define his own exception.) >> >> Could you give an example of what you're trying to do? (The >> above isn't sufficiently informative.) > > Thanks for the answers. Sure I can provide more details. Let us > consider the following constructor: > > == > public FileStream () > { > try > { > outputFile = new BufferedWriter(new FileWriter("hello.txt")); > } > catch (IOException cantWriteInFile) > { > System.out.println("Impossible to write (in) hello.txt."); > System.exit(1); > } > } > == > You saw that I had to catch an IOException, as expected when dealing > with a BufferedWriter. > > Now, in a function of the same class of the constructor (class > FileStream), I need to write in the output file. As a result, I've got > > == > public void write (String outputText) > { > try > { > outputFile.write(outputText); > outputFile.close(); > } > catch (IOException cantWriteInFile) > { > System.out.println("Impossible to write (in) hello.txt."); > System.exit(1); > } > } > == > > You directly notice that the two catch blocks are identical. As a > result, I'd like to do something like this (in pseudocode): > > == > public FileStream () > { > try > { > outputFile = new BufferedWriter(new FileWriter("hello.txt")); > } > catch (IOException cantWriteInFile); > } > == > then, later in the file: > > == > public void write (String outputText) > { > try > { > outputFile.write(outputText); > outputFile.close(); > } > catch (IOException cantWriteInFile); > } > == > where IOException cantWriteInFile is defined in the class as > > == > System.out.println("Impossible to write (in) hello.txt."); > System.exit(1); > == > > Is there a way to do this? It looks terribly bad to have the same > catch code in two different methods. See Stefan Ram's answer. However, it seems to me that what you want to do reeks of bad design. For many simple programs it's true that an I/O error is reason for termination -- but even for simple programs it is *not* a good idea for low-level code to yank the rug out from beneath the rest of the program. The low-level code is not aware of the wider context in which it's being used, and is not in a good position to make global decisions about the program's state and fate. Poor analogy: You leave your coat at the cleaners', and they notice that one of the buttons has come off. "Imperfect coat," they say, and burn it: They're sure you wouldn't want to wear an imperfect coat, and they think they're doing you a favor by relieving you of the expense of cleaning it. What they didn't know is that you've got a needle and thread and are fully able to reattach the button -- except that the coat's been burned. They made a global decision on the basis of a local context. If you can't do anything constructive about an exception, the best policy is usually to re-throw it, or not to catch it in the first place. Change your constructor and method to public FileStream throws IOException { ... } public void write(String text) throws IOException { ... } If the caller can do something constructive (try a different file, perhaps?), the caller can catch your IOException and take a different course. If the caller is helpless, it, too, can let the exception propagate outwards to its caller, and to callers at higher and higher levels. If nobody ever catches it, that means nobody was prepared to deal with the situation and the program will terminate anyhow. But if somebody along the way *can* cope with the problem, you've allowed them to do so instead of burning the coat. -- Eric Sosman esosman@ieee-dot-org.invalid