[Biojava-dev] Errors versus Exceptions

Mark Schreiber markjschreiber at gmail.com
Thu May 20 04:02:12 UTC 2010


Sorry, you lost me on that thread. What are we avoiding like the plague?

On Tue, May 18, 2010 at 5:55 PM, Andy Yates <ayates at ebi.ac.uk> wrote:
> Now that's the situation we want to avoid like the plague :)
>
> On 18 May 2010, at 10:51, PATERSON Trevor wrote:
>
>>> You can make it safe using all
>>> kinds of best practices from Bloch's effective Java (private
>>> setters, no public constructers etc) but that makes it quite
>>> a bit harder for people who are newer to Java (and are used
>>> to bean like patterns)
>>
>> I'm not new to Java :)
>> But bean properties and public setters and constuctors are kind of central to the
>> idea of lazy load and datamapping through Ibatis ...
>> There maybe there does come a point where:
>> "hey if I can't make and use these biojava objects without jumping through enormous hoops
>> I'll just make my own objects..."  - which obviously would be 'bad'.
>>
>>
>> trevor
>>
>>
>>
>>
>>> -----Original Message-----
>>> From: Mark Schreiber [mailto:markjschreiber at gmail.com]
>>> Sent: 18 May 2010 10:24
>>> To: PATERSON Trevor
>>> Cc: Andy Yates; biojava-dev at lists.open-bio.org
>>> Subject: Re: [Biojava-dev] Errors versus Exceptions
>>>
>>> The script example is a good one. If you truly want to do
>>> something quick and dirty you could use BioJava with Groovy
>>> and ignore exceptions completely.  This also eludes to a
>>> problem with making BioJava easy to use and safe.
>>>
>>> I have come to the conclusion that you can't really make a
>>> Java API easy for beginners. You can make it safe using all
>>> kinds of best practices from Bloch's effective Java (private
>>> setters, no public constructers etc) but that makes it quite
>>> a bit harder for people who are newer to Java (and are used
>>> to bean like patterns). Alternatively you can use bean like
>>> patterns (useful in JEE settings) at the great danger that
>>> people will corrupt objects using public setters and cause
>>> all kinds of concurrent problems with threads. An experience
>>> developer should be able to handle both. Someone new will
>>> struggle with both.
>>>
>>> Languages like Groovy might be best for the casual or new
>>> user. Very quick to get up and running and somewhat safe
>>> (scripting languages are never really safe). It wouldn't be
>>> too hard to make some convenience Groovy objects; you could
>>> make a GSequence for example to make use of Groovy's
>>> overloaded operators.
>>>
>>> Anyhow, making BioJava easier to use was one argument for
>>> making exceptions inherit from RuntimeException. Ultimately I
>>> don't think we made it easier to use for beginners although
>>> it did make code tidier and hopefully forced people to think
>>> about defensive code.
>>>
>>> - Mark
>>>
>>> On Tue, May 18, 2010 at 5:06 PM, PATERSON Trevor
>>> <trevor.paterson at roslin.ed.ac.uk> wrote:
>>>>
>>>>
>>>>> 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?
>>>>
>>>> I think it depends on what level your application is
>>> working at - if
>>>> your application is just a script doing some data munging
>>> maybe that
>>>> is a fatal exception that you want to cause the script to
>>> die gracefully...
>>>> But if you are running a large graphical display program
>>> and you ask
>>>> for the sequence of have a particular component  - you need to be
>>>> catching the exception and handling the failed request
>>>>
>>>> That's my 2.5p ;)
>>>>
>>>> Trevor
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>> -----Original Message-----
>>>>> From: Andy Yates [mailto:andyyatz at gmail.com] On Behalf Of
>>> Andy Yates
>>>>> Sent: 18 May 2010 09:53
>>>>> To: Mark Schreiber
>>>>> Cc: PATERSON Trevor; biojava-dev at lists.open-bio.org
>>>>> Subject: Re: [Biojava-dev] Errors versus Exceptions
>>>>>
>>>>> 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.
>>
>
> --
> 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/
>
>
>
>
>




More information about the biojava-dev mailing list