[Biojava-dev] Errors versus Exceptions
PATERSON Trevor
trevor.paterson at roslin.ed.ac.uk
Tue May 18 09:31:34 UTC 2010
In our use case the lazy loading is dependent on remote ensmebl mysql access - through Ibatis ;)
It is already a headache :(
> -----Original Message-----
> From: Mark Schreiber [mailto:markjschreiber at gmail.com]
> Sent: 18 May 2010 10:28
> To: PATERSON Trevor
> Cc: Andy Yates; biojava-dev at lists.open-bio.org
> Subject: Re: [Biojava-dev] Errors versus Exceptions
>
> Yikes! OK, in that case you will need to declare IOExceptions
> in lots of places. In this day and age I would not advise
> making your lazy loading dependent on a file system. You will
> need to allow for distributed FS's, databases, AmazonS3,
> distributed memory caches.
> Could turn into a bit of a headache
>
> - Mark
>
> On Tue, May 18, 2010 at 5:22 PM, PATERSON Trevor
> <trevor.paterson at roslin.ed.ac.uk> wrote:
> > 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.
> >
> >
>
--
The University of Edinburgh is a charitable body, registered in
Scotland, with registration number SC005336.
More information about the biojava-dev
mailing list