BioUML exceptions

From BioUML platform
Revision as of 17:58, 22 July 2013 by Tagir Valeev (Talk | contribs)

Jump to: navigation, search
This page or section is under construction right now.

This article describes new BioUML exception handling concept introduced in version 0.9.6.

Contents

Overview

BioUML exceptions (short: BUEX) are descendants of class BioUMLException. All other exceptions are called raw exceptions. Now it's undesired to throw raw exception in BioUML code except some cases when particular part of code can become BioUML-independent.

Class BioUMLException extends RuntimeException, thus it's not necessary (but desired!) to declare it in throws clause.

Exception levels

Exceptions are divided to several categories called exception levels. Low-level BioUML exceptions include:

System
Low level errors: out of memory, NPE, programmatic errors, etc.
SQL
Low level SQL database access problem
IO
Low level input/output access problem
Network
Low level network problem

High-level BioUML exceptions include:

Repository
Repository problem (unable to get, put, delete element, etc.)
Security
Access violation, quota, etc.
Computational
Computational problem during some data analysis
Parameter
User input problem

List of levels may change in future. Every level has its base exception class. For example, exceptions of level 'System' are related to BioUMLSystemException and its subclasses.

Exception properties

Each BioUML exception has the following properties:

ID
Autoincrementing number starting from 1 identifying the exception.
Level
Exception level (described above)
Code
Text string which together with level refers to particular error situation. For example, code 'NPE' of level 'System' refers to null pointer exception. Usually level and code are written together as 'System.NPE'
Logging level
How this exception should be displayed in log:
  • None - Do not log this Exception even if requested
  • Summary - Log summary
  • Parameters - Log summary+properties
  • Trace - Log summary+properties+trace

Also BioUML exception has custom properties defined in DynamicPropertySet. They can be logged and used in generating user-friendly messages.

Chaining

BioUML exceptions can be chained. Usually (but not always) high-level exception has low-level exception cause, which may have raw exception as the cause. Every raw exception can be converted to BioUML exception using ExceptionRegistry.translateException(Throwable) method (if BioUML exception was passed to this method it will just return it). However in many cases it's desired to create BioUML exception manually as you may specify additional details. BioUML exception should not be the cause of raw exception. Low-level exception should has raw exception or nothing as the cause (not another BioUML exception).

Reporting

Error log in BioUML workbench.

There are two ways to report the BioUML exception: to display it to user and to log it. All BioUML exceptions are logged into special logger error.log. In BioUML workbench it's displayed as a separate sub tab of Application log viewpart. On BioUML server this might be appended to separate file depending on your server.lcf configuration. Ideally all low-level technical information including all the stacktraces must go there. Messages displayed to the user (including ones displayed in normal Application log) should be more user-friendly.

For example, this is how the exception is reported in Application log:

ERROR :  Cannot create collection data/Collaboration/Lan_test/Data/MACS/profile
Error reason: Internal error occured (Java class ru.biosoft.bsa.analysis.chipseqprofile.PeakProfileTransformer not found). Please check error log for BUEX#136.

And this is how the same exception is reported in Error log:

ERROR :  BUEX#137/Repository.CannotCreate: Cannot create collection data/Collaboration/Lan_test/Data/MACS/profile
Caused by: BUEX#136/System.NoClass: Internal error occured (Java class ru.biosoft.bsa.analysis.chipseqprofile.PeakProfileTransformer not found).
Caused by: java.lang.ClassNotFoundException: Can't load class ru.biosoft.bsa.analysis.chipseqprofile.PeakProfileTransformer
       at ru.biosoft.access.CollectionFactory.loadClass(CollectionFactory.java:269)
       at ru.biosoft.access.TransformedDataCollection.<init>(TransformedDataCollection.java:45)
       at sun.reflect.GeneratedConstructorAccessor12.newInstance(Unknown Source)
       at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
       at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
       at ru.biosoft.access.CollectionFactory.createCollection(CollectionFactory.java:195)
       at ru.biosoft.access.CollectionFactory.createCollection(CollectionFactory.java:148)
       at ru.biosoft.access.LocalRepository.createCollection(LocalRepository.java:224)
       at ru.biosoft.access.LocalRepository.init(LocalRepository.java:131)
(many more stacktrace lines)

To log the exception, use BioUMLException.log() method. Each exception can be logged only once in order not to pollute the error log with dublicates.

To get the user-friendly message use BioUMLException.getMessage() method. This method provides one-line description of the problem followed by the description of the cause. If cause is absent or it's raw exception, it's not returned. By default for low-level exceptions additional message added like Please check error log for BUEX#... for BioUML workbench or Please contact application vendor supplying ID BUEX#... for BioUML server.

Message templates are registered currently in the static section of ExceptionRegistry class. In future this might be changed to some kind of extension point. Templates can use all custom properties defined by exception referring to them like $path$. Bean properties of these properties can also be used like $cause/class/simpleName$ (the same syntax is used by OptionEx.makeAutoProperty).

Usage guidelines

Try not to 'swallow' the exception if you cannot handle it properly. Printing the exception to log and returning null is bad practice as calling code won't know what's going on. Also printing to the log might be useless for BioUML web edition as messages from your log object may not be passed to the client at all. Consider wrapping the exception to higher-level BioUML exception and throw it outside. If you think that user might be interested in exception, but you can continue ignoring it, use ExceptionRegistry.log(Throwable), which will translate an exception to BioUML exception, log it and return the user-friendly message.

Currently the prefered way to get the data element is DataElementPath.getDataElement(Class<T>). The parameter is the wanted element class. This method never returns null. Instead it throws BioUMLRepositoryException if element cannot be fetched or has invalid class.

Personal tools
Namespaces

Variants
Actions
BioUML platform
Community
Modelling
Analysis & Workflows
Collaborative research
Development
Virtual biology
Wiki
Toolbox