[Biojava-dev] Errors versus Exceptions
Andy Yates
ayates at ebi.ac.uk
Tue May 18 09:55:07 UTC 2010
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