Path: csiph.com!x330-a1.tempe.blueboxinc.net!feeder1.hal-mli.net!feeder.news-service.com!news.albasani.net!.POSTED!not-for-mail From: Lew Newsgroups: comp.lang.java.help Subject: Re: Some same exceptions used in a given file Date: Sat, 23 Apr 2011 20:19:27 -0400 Organization: albasani.net Lines: 131 Message-ID: References: <87r58s28w3.fsf@merciadriluca-station.MERCIADRILUCA> <871v0smxvr.fsf@merciadriluca-station.MERCIADRILUCA> <877hakftbs.fsf@merciadriluca-station.MERCIADRILUCA> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Trace: news.albasani.net 9BxsFH/bkyi8SRZnByw+0bcKHQZ9ftcptybDB9JxlN3UYctOCbks/KXcpeYIxReYRhk2iEiWy54kajVSX8O/bQ== NNTP-Posting-Date: Sun, 24 Apr 2011 00:19:19 +0000 (UTC) Injection-Info: news.albasani.net; logging-data="OCKaO44+5QxuLn0KFadU/r6YWvCQebZJEsMAN+9kvgKuaquofdsJlXgy/hzjSSd+rytMkBBS6SauIWWNrUfONFzFW1FpkKBdcYdUVakY1JdepjM0ytYq1519Rd6clCv9"; mail-complaints-to="abuse@albasani.net" User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.14) Gecko/20110223 Thunderbird/3.1.8 In-Reply-To: <877hakftbs.fsf@merciadriluca-station.MERCIADRILUCA> Cancel-Lock: sha1:VT2X4YIRhpyn3qu4dq9kwyswb0k= Xref: x330-a1.tempe.blueboxinc.net comp.lang.java.help:630 Merciadri Luca wrote: > Thanks for the example. And now if another method of the same class > throws also an IOException, but whose action needs not to be the same? > > For example, how would I convert > > == > public void foo > { > try > { > // ... > } > > catch (IOException problem1) > { > > } > > } > > public void bar > { > try > { > // ... > } > > catch (IOException problem2) > { > > } > > } > == > > ? > > I might do > > == > public void foo throws IOException > { > // ... > } > > public void bar throws IOException > { > // ... > } > == > > and then catch the exception in the caller, but how do I differentiate > from problem1 to problem2? Sorry for this silly question, but it seems > not that habitual regarding Google answers on this. There are a few approaches. Right now you're starting from the leaf level of how to implement try-catch and trying to glean an overall strategy. A better approach is the exact opposite: Decide on your overall *application-domain* strategy first. As you code in various layers of your application, think of a type as part of the internal API for the application - a one-shot library. Good O-O principles dictate that a compoment have a well-defined purpose and external contract for interaction with other components. None of those strategic conversations involve exceptions as such - just conditions and desired responses and state transitions involving those conditions. At the nitty-gritty detail level of implementation, OTOH, exceptions signal out-of-band issues - things that stop the action. But their effect is local - not strategic, but specific to a particular action in service of that strategic effect. Since the strategic conversation is exception-agnostic, the component must convert that exceptional condition into the appropriate response that accords with its contract for interaction. That contract varies with the layer involved. If the layer is a deeper one, say a data-access layer (DAL), it functions exactly like an API. Again, define its contract from the outside - what should API clients experience? Sometimes that means that a particular API method has an 'Exception' subtype as part of its contract. But that is dictated by the strategic purpose of the API, not by knee-jerk, thoughtless reactions to lower-level events. That upward view often comprises an application-specific exception, one that tells the application "something lower broke", and then uses the 'cause' attribute to say what. How fine-grained does the top level view have to be, for Pete's sake? Why be so obsessive-compulsive? Usually the 'cause' chain and stack trace contains everything needed for debugging, and nothing needed for the strategic upline viewpoint. Usually. So here's how you convert low-level exceptions to higher-level ones, if (and only if) that's what your strategy requires: public void actByContract( Foo stimulus ) throws LewsException { BufferedReader reader; try { reader = new BufferedReader( new FileReader( stimulus.getFile() )); } catch ( IOException exc ) { final String msg = "actByContract() broke"; logger.error( msg, exc ); LewsException lewx = new LewsException( msg, exc ); throw lewx; } ) Key points: - Log and act upon exceptions at the lowest point they occur, if they aren't one of your own wrapper exceptions like 'LewsException'. - Don't let exceptions walk all the way out of an application or lower-level exceptions out of a component - convert them to some strategically valid, contract-authorized interactions with outsiders. - Do determine the strategically and contractually valid interactions for the application and every component, first, before implementation. - Do allow only strategically and contractually valid interactions to occur and none other. -- Lew Honi soit qui mal y pense. http://upload.wikimedia.org/wikipedia/commons/c/cf/Friz.jpg