[Biojava-dev] Errors versus Exceptions
PATERSON Trevor
trevor.paterson at roslin.ed.ac.uk
Tue May 18 09:22:39 UTC 2010
Yes... But...
If our implementation relies on a lazy load underneath every Sequence method implementation..
Then every method can throw an IO type Exception
In essence you can instantiate a valid Sequence object with a LazyLoading Reader before you get the valid SequenceData,
unlike the case where you can check that you can make a valid Sequence object from the Reader.
> -----Original Message-----
> From: Mark Schreiber [mailto:markjschreiber at gmail.com]
> Sent: 18 May 2010 10:11
> To: Andy Yates
> Cc: PATERSON Trevor; biojava-dev at lists.open-bio.org
> Subject: Re: [Biojava-dev] Errors versus Exceptions
>
> Your ability to recover really depends on the context and how
> much effort you want to make. If you are in a long running
> app on a server you should try very hard to recover or at
> least fail gracefully without crashing. For small programs,
> who cares? In interactive contexts you can request feedback
> from the user. For example, if your FASTA file is not FASTA
> you could ask for another file.
>
> Clarifying a little more, Unchecked exceptions are for things
> that could easily be avoided if the API allows for it by
> doing simple checks (testing for null, validating input etc).
> Checked exceptions should be for things that are difficult to
> check or can be unpredictable; IOException is a good example.
> An IOException can happen because of something completely out
> of your control. It needs to be checked because defensive
> programming is near impossible; you could check that a file
> exists but a sporadic network failure between calls might
> make it unreachable. Finally, Errors are for the
> unrecoverable. Things that will probably even bring down a
> long running app or server app (or at least require some
> reconfiguration or redeployment).
>
> I think a well designed API can make most exceptions
> unchecked (and avoidable with good programming), small
> numbers of Checked exceptions for things that can't be
> avoided with defensive programming and a very small number of
> things that can cause errors.
>
> - Mark
>
> On Tue, May 18, 2010 at 4:52 PM, Andy Yates <ayates at ebi.ac.uk> wrote:
> >
> > You've made that previous decision a lot harder now Mark (I
> knew it was over too quickly).
> >
> > On reflection I'm not sure how well you can recover from
> something like an unknown compound. When you hit that
> exception what are you going to do with it? Something like
> IOExceptions for a file not being open you can do something
> about that (say it's NFS you could always retry after an
> allotted amount of time has passed). But an unknown compound
> ... not sure how you can deal with that apart from callbacks
> in the parsers. If you think of this in terms of FASTA input
> into an aligner program and you have an unknown compound
> there all you're going to do is to pass a message back to the
> user saying you didn't understand the input sequence with the
> error message from the Exception something like "Compound '?'
> is not supported". You could always recover attempting to
> move through different CompoundSets seeing if one works but
> are you going to do that?
> >
> > I guess the thing to do is to start with checked exceptions
> in potentially recoverable situations and if they prove to be
> too clumsy then as BioJava did previously we will switch to
> the RuntimeException as a base class. We should also
> endeavour to pass on exceptions and avoid excessive exception
> wrapping.
> >
> > I do think there is a situation where we can relax these
> rules; I would like to see the relaxation of them when a
> developer is building say a DNASequence but only using a
> String. The same should happen for helper classes.
> >
> > That's my 2p :)
> >
> > Andy
> >
> >
> > On 18 May 2010, at 04:53, Mark Schreiber wrote:
> >
> > > To give some historical perspective. This started happening in
> > > BioJava 1.5. We switched BioException to extend RuntimeException
> > > (which is not checked). This came from some thinking at the time
> > > that Java's exception checking was a little bit broken (as
> > > exemplified by BioJava). Checked exceptions are good as
> long as you
> > > don't swallow them in the API or just use them to spew a stack
> > > trace. Spitting a stack trace is pointless as the JVM
> will do a much
> > > better job of this when it dumps you out. Swallowing them
> in the API
> > > is stupid because it is the developer who needs to do
> something with
> > > it. Unless it is truly an Error which is the only time an Error
> > > should be used (unrecoverable problems).
> > >
> > > RuntimeExceptions should be used for any type of
> exception that can
> > > be avoided by defensive programming. NullPointerExceptions and
> > > IndexOutOfBounds exceptions are classic examples. There
> are hundreds
> > > of places in Java where you could get one of these but you can
> > > easily avoid them by checking if a collection contains an item,
> > > doing simple if( x == null) checks, using array.length
> etc. For this
> > > reason these and some other Java exceptions extend
> RuntimeException
> > > and are not checked. Can you imagine what Java would look like if
> > > you actually had to put every array access in a try,
> catch statement?
> > >
> > > Therefore, as much as possible I think BioJava3 should have
> > > exceptions that extend RuntimeException and provide a defensive
> > > mechanism to avoid having them happen. For example in
> creating a DNA
> > > sequence from text you could provide a validator which
> will check if
> > > there are any "incorrect" characters. Good code examples
> on the wiki
> > > should show the use of defensive programming and not just
> surround
> > > everything with a try catch. Importantly
> RuntimeExceptions should
> > > be declared so people are aware they may occur. This is
> not required
> > > by the compiler but it is good practice for documentation
> purposes.
> > > The Exception class itself should probably contain some Javadoc
> > > which explains how it can be avoided in the first place. Checked
> > > exceptions are good for cases where you can recover
> (although this
> > > is often more challenging than people think) but it is
> always easier
> > > and faster to check yourself, throwing the exception and
> generating
> > > the stacktrace etc takes quite a lot of effort from the JVM.
> > >
> > > Finally, I don't think you should be throwing Errors to often.
> > > Although Errors are unchecked and give you the same effect as
> > > RuntimeExceptions they imply something really bad has gone wrong.
> > > These should be reserved for things like configuration
> files being
> > > corrupt or things that would prevent BioJava from being
> used, like
> > > not finding a required JAR file or plugin. You can't
> recover from these.
> > > If your API has lots of places where Errors can occur it might
> > > indicate poor design.
> > >
> > > - Mark
> > >
> > > On Mon, May 17, 2010 at 10:30 PM, Andy Yates
> <ayates at ebi.ac.uk> wrote:
> > >>
> > >> There's something that irks me with checked exceptions &
> I found code worked better once I went to a fail-fast method
> of coding but for an API I can see the usefulness of them.
> > >>
> > >> Wow I think this could be the fastest any group has ever
> dealt with
> > >> the Checked/Unchecked exception argument :)
> > >>
> > >> Andy
> > >>
> > >> On 17 May 2010, at 14:58, PATERSON Trevor wrote:
> > >>
> > >>>
> > >>>
> > >>>> Is the problem in the code the fact that errors are
> used or that
> > >>>> they are not declared on the method signatures?
> > >>>
> > >>> Declaring them would help - but
> > >>> Even if you declare Errors in the signature, there is
> nothing to force you to catch them.
> > >>> So nothing to alert you to the chance that they may be
> thrown when you are writing code.
> > >>>
> > >>> public class Demo {
> > >>>
> > >>> public static void main(String[] args) throws Exception{
> > >>>
> > >>> Demo.demo();
> > >>> System.out.println("never reached");
> > >>>
> > >>> }
> > >>>
> > >>> public static void demo() throws Error {
> > >>> throw new Error("kills the runtime");
> > >>> }
> > >>> }
> > >>>
> > >>> Compiles OK with or without declaring the throwable -
> but throws a runtime error.
> > >>>
> > >>> :. IMHO throwing errors is not very useful to developer
> > >>> - they can use them - IF they know the code well enough to know
> > >>> they might be thrown
> > >>>
> > >>> If Exceptions were used
> > >>> 1. they would HAVE to be dealt with - if a developer
> just swallows
> > >>> something bad, than that's their responsibility for
> shitty code ;)
> > >>> 2. like Errors they would be extendable, so real case
> dataloaders
> > >>> could use their own exception types and decide how to
> deal with or
> > >>> ignore them
> > >>>
> > >>> I guess in my background of coding for data access over
> the wire
> > >>> with jdbc and webservices
> > >>> - you need to be aware of the real probability of
> connection and
> > >>> request failures
> > >>> - so explicitly using Exceptions forces the developer to code
> > >>> defensively
> > >>>
> > >>>
> > >>>
> > >>>
> > >>>>
> > >>>> On a more design note I do not like checked exceptions for two
> > >>>> reasons. The first is they seem to make more junior developers
> > >>>> catch Exception and swallow it. The second is whenever
> I've been
> > >>>> Java coding in the past whenever a checked exception
> gets thrown
> > >>>> (say IOException because of incorrect file
> permissions) I cannot
> > >>>> deal with it which in the past has meant I either
> forward on the
> > >>>> problem or re-throw in an unchecked exception.
> > >>>>
> > >>>> That said as Scooter mentioned the exception system was rushed
> > >>>> out in the hackathon and did not have much work put into it.
> > >>>>
> > >>>> Andy
> > >>>>
> > >>>> On 17 May 2010, at 13:15, PATERSON Trevor wrote:
> > >>>>
> > >>>>> resending cos of bad headers
> > >>>>>
> > >>>>> ________________________________
> > >>>>>
> > >>>>> From: PATERSON Trevor
> > >>>>> Sent: 17 May 2010 13:02
> > >>>>> To: biojava-dev at lists.open-bio.org
> > >>>>> Subject: Errors versus Exceptions
> > >>>>>
> > >>>>>
> > >>>>> Could I ask a quick question about why BJ3 seems to use
> > >>>> Errors rather
> > >>>>> than Exceptions
> > >>>>> - maybe this is already documented somewhere on the wiki
> > >>>> for BJ3 or 1 - and you can point me there.
> > >>>>>
> > >>>>> Obviously for us dataloading from remote databases we need
> > >>>> to have a method to catch connection,sql, datamapping
> errors etc.
> > >>>>> We ususally throw DataAccessExceptions when this happens,
> > >>>> which wrap any java.net, Ibatis and SQL exceptions.
> > >>>>>
> > >>>>> It is difficult for us to plug in our lazyload over your
> > >>>> signatures in
> > >>>>> the BJ3 sequence readers, as these don't throw exceptions,
> > >>>> because you
> > >>>>> seem to use Errors throughout - which dont need to be
> > >>>> declared. Infact I cant actually see examples of you
> catching and
> > >>>> responding to thrown errors.
> > >>>>>
> > >>>>> for example the setContents routine of the Sequence Readers
> > >>>> throws a
> > >>>>> CompoundNotFoundError if there is no mapping for a base -
> > >>>> but I can't see what is done with this.
> > >>>>>
> > >>>>> According to the Java Lang Spec, errors are used for
> > >>>> "serious problems
> > >>>>> that a reasonable application should not try to catch" -
> > >>>> but I would
> > >>>>> have thought finding an unrecognized base in a sequence was
> > >>>> just the
> > >>>>> sort of thing that should be thrown and caught and acted
> > >>>> on. As error
> > >>>>> throwables are not reported in the signature - developers
> > >>>> don't have
> > >>>>> any clue ( or requirement) that they should be catching and
> > >>>>> dealing with errors - which seems a bit dangerous to me... If
> > >>>> Exceptions were
> > >>>>> thrownrather than Errors that would force the developer to
> > >>>>> handle runtime errors
> > >>>>>
> > >>>>> Cheers Trevor
> > >>>>>
> > >>>>> --
> > >>>>> The University of Edinburgh is a charitable body,
> registered in
> > >>>>> Scotland, with registration number SC005336.
> > >>>>>
> > >>>>>
> > >>>>> _______________________________________________
> > >>>>> biojava-dev mailing list
> > >>>>> biojava-dev at lists.open-bio.org
> > >>>>> http://lists.open-bio.org/mailman/listinfo/biojava-dev
> > >>>>
> > >>>> --
> > >>>> Andrew Yates Ensembl Genomes
> Engineer EMBL-EBI
> > >>>> Tel: +44-(0)1223-492538 Wellcome Trust Genome Campus Fax:
> > >>>> +44-(0)1223-494468 Cambridge CB10 1SD, UK
> > >>>> http://www.ensemblgenomes.org/
> > >>>>
> > >>>>
> > >>>>
> > >>>>
> > >>>>
> > >>> --
> > >>> The University of Edinburgh is a charitable body, registered in
> > >>> Scotland, with registration number SC005336.
> > >>>
> > >>>
> > >>> _______________________________________________
> > >>> biojava-dev mailing list
> > >>> biojava-dev at lists.open-bio.org
> > >>> http://lists.open-bio.org/mailman/listinfo/biojava-dev
> > >>
> > >> --
> > >> Andrew Yates Ensembl Genomes Engineer
> EMBL-EBI
> > >> Tel: +44-(0)1223-492538 Wellcome Trust Genome Campus Fax:
> > >> +44-(0)1223-494468 Cambridge CB10 1SD, UK
> > >> http://www.ensemblgenomes.org/
> > >>
> > >>
> > >>
> > >>
> > >>
> > >> _______________________________________________
> > >> biojava-dev mailing list
> > >> biojava-dev at lists.open-bio.org
> > >> http://lists.open-bio.org/mailman/listinfo/biojava-dev
> >
> > --
> > Andrew Yates Ensembl Genomes Engineer
> EMBL-EBI
> > Tel: +44-(0)1223-492538 Wellcome Trust Genome Campus Fax:
> > +44-(0)1223-494468 Cambridge CB10 1SD, UK
> > http://www.ensemblgenomes.org/
> >
> >
> >
> >
>
--
The University of Edinburgh is a charitable body, registered in
Scotland, with registration number SC005336.
More information about the biojava-dev
mailing list