[Biojava-dev] Errors versus Exceptions

Andy Yates ayates at ebi.ac.uk
Tue May 18 09:27:38 UTC 2010


Doesn't that bring it back to unchecked exceptions?

On 18 May 2010, at 10:22, PATERSON Trevor 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.
> 

-- 
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