At the moment i working with library which can throw hell alot of different exceptions(8-10 per method call) and most of them must be handled, worse of all every method (at any time) can throw AuthenticationExpiredException, and i must re-attempt to authenticate. For example:
try {
xStream = xSet.createXStream(id, binding, mimeType); //Method call
} catch (AuthenticationExpiredException authenticationExpiredException) {
try {
this.authenticate(); // re-authenticate
xStream = xSet.createXStream(id, binding, mimeType); //Method call again
} catch (XAMException xamException) {
throw new ConnectorException(
"Error occurred during creating new Blob after attempting to re-authenticate",
xamException);
}
} catch (XSystemCorruptException xSystemCorruptException) {
this.entities.clear();
this.closeConnection();
throw new ConnectorException("XSystem was corrupt and connection was closed",
xSystemCorruptException);
} catch (XSetCorruptException xSetCorruptException) {
this.closeEntity(entity);
throw new ConnectorException("XSet for entity: " + entity.getXuid()
+ " was currupt and removed", xSetCorruptException);
} catch (XAMException xamException) {
throw new ConnectorException(
"Error occurred during creating new Blob.", xamException);
}
And this is one of the smallest examples of exception handling. The main question here, is there any way to reduce amount of code which handle exceptions, and make logic cleaner?
UPDATE
Thanks for your feedback. I decided to create separate wrapper for this library by wrapping every method and handling them respectively. To support different handling methods i created interface for wrapper and then implemented it with my custom wrapper like this:
public interface XAMLibraryWrapper{
// Methods
}
/**
* Will attempt to recover before throwing RuntimeException
*/
public class RecoveringXAMLibraryWrapper implements XAMLibraryWrapper{
// Implementation
}
If there is a consistent way to handle those method (i.e. you always wrap them in the same way and re-throw a RuntimeException, then a custom wrapper library might be the appropriate approach. This can still work when there are 2-3 different ways to handle them (by providing 2-3 wrapper methods (or even classes) for a single wrapped method/class).
Alternatively, if two or more exception types have the exact same handling code, then you can try to look for Java 7 to get multi-catch.
You can use Template method pattern. JdbcTemplate is a wonderful example how this design pattern can simplify exception-heavy code (SQLExceptions in this case).
If the API is indeed designed to throw that many exceptions, and each of them requires different handling, then there isn't much you can do.
One thing you can do is move repeated code in a separate method, or use Java 7 multi-catch.
If you have different things to do for each exception I'm afraid all those catch statements might be necessary. However, if you have lot's of catch statements with the same content or lot's of resources to close, you might have a look into the new Java 7 features like multiple exceptions in one catch and automatic resource handling. I'm not sure Java 7 is an option for you though.
Related
Small Java question regarding object instantiation and logging please.
In our (way too big) project we have one particular exception MyCustomException which is thrown.
The usual code will be something like:
if (conditionNotMet()) {
throw new MyCustomException();
try {
} catch (SomeException e) {
throw new MyCustomException();
There are a good thousands of throws of this kind.
And for all of them, we would like to add logging, something like:
if (conditionNotMet()) {
LOGGER.error(something bad happened, throwing a new MyCustomException());
throw new MyCustomException();
try {
} catch (SomeException e) {
LOGGER.error(something bad happened, throwing a new MyCustomException());
throw new MyCustomException();
As you can imagine, since we have thousands and thousands of those, we are wasting tremendous times adding the LOGGER in all the places.
I was wondering, is there some kind of annotation we can put on the MyCustomException, something like:
#LogMeWhenIamCreated
public MyCustomException(...) {
So we can put this annotation in only one place, and still be able to see the logs we want, without us having to go through the entire code base and the thousands of throws?
Thank you
I see three options here:
Use AOP to handle creation of MyCustomException. Follow this answer to see how you can write the aspect for class creation. It's also possible to write aspect for #LogMeWhenIamCreated annoptation.
Use regex to find all throw new MyCustomException(); constructions and add logging before throwing. The disadvantage is obvious - a lot of changes.
Add logging to the MyCustomException constructor as Rohan suggested.
The disadvantage for options 1 and 2: if you have places where you construct the exception and don't throw it, the log message will still be added.
Sometimes I reclass an exception like this:
try{
methodA(param1);
}catch(ExceptionType1 ex){
throw new ExceptionType2(ex);
}
An example of when I do this is when methodA's params should be safe and will not throw exceptions, so the ExceptionType1 is really indicative of a different problem (something like ExceptionType2).
This is not reclassing from checked exception to unchecked.
There's nothing wrong; in fact it's a commonly used pattern.
Rethrowing an exception wrapped in another exception is often used when the method contract throws a domain specific exception, but there's an implementation specific exception you must deal with, for example an SQLException.
public Customer getCustomer(int id) throws CustomerDataUnavailableException {
try {
// access SQL database
return customer;
} catch ( SQLException e) {
throw new CustomerDataUnavailableException(e);
}
}
The choice to store customer data in an SQL database is an implementation choice, which you don't want to leak out through the API (by throwing SQLException).
It also makes changing the implementation easy, for example using a flat file system on a mobile device, or using a NoSql db - the change can be made to the method without changing any other code, because the API contract is implementation independent.
Finally, it makes testing and mocking easier - you don't have to throw exotic exceptions, the classes of which may not even be accessible to your testing code.
It is OK - according to this URL, this is defined as a "chained exception" and it is legal:
http://docs.oracle.com/javase/tutorial/essential/exceptions/chained.html
The following example shows how to use a chained exception.
try {
} catch (IOException e) {
throw new SampleException("Other IOException", e);
}
I would document the different types of exceptions using the #throws tag for JAVADOC. It is legal to include multiple #throws tags for one method; see this URL:
Can I use multiple #throws tags for the same exception in Javadoc?
In my class I'm doing validation of custom data. Many conditions apply. Upon any failure, I want to throw a specific MyException. Throwing this MyException takes many common parameters, and one custom parameter (based upon the actual failure). So an actual throw takes many characters to write and destroys tidyness because of code duplication. Also I have to throw it too much times. I made up my mind to create a private method that prepares and returns a new instance of this MyException and takes the only custom data as parameter, so the code can be much cleaner.
private MyException createMyException(final CustomErrorData errorData)
{
... some info gathering, parameterizing, etc...
return new MyException(errorData);
}
...
So throwing a new MyException is much shorter:
throw createMyException(errorData);
My question is: what's the correct practice to prevent code duplication in this case? I may be overmistifying Exceptions.
An Exception factory - never seen it before but at least it sounds like a proper design.
I just worry - you seem to put quite a lot effort on designing an exception throwing framework: adding parameters, states, etc. to exceptions. Do you really encounter that many exceptional conditions in your code? Or do you throw exceptions where proper handling of expected conditions would?
Usually a thrown exception is "just for the logs". Something happened that shouldn't have happened in the current context. Something, the developers should know and correct in the next release. We shouldn't use exceptions to handle expected states.
So before investigating in brilliant exception creation code, double-check if it's worth the effort or if the design of your application is starting to get ... too creative.
If you have one general type of exception you will lose some of the advantages of OOP.
Instead of being able to have try-catch for specific exception types you will have to have a catch for your general exception and then continue processing based on some fields inside your MyException class.
You will have something like this:
try{
//code here
}
catch (MyException ex){
switch(ex.exceptionType){
case IOException: doSomething();break;
case ConnectionException:doSomethingElse();break;
default: //throw the exception outwards if you don't want to process it
}
}
When instead you should have something like
try{
//code here
}
catch (IOException ex){
doSomething();
}
catch (ConnectionException ex){
doSomethingElse();
}
which is more clear and more OOP.
Why you would place all your exceptions under a general type is something of a puzzle, it's like making all your objects to be instances of only one class, but you would require of them different behaviors based on some flags.
Imho your helper function is perfectly fine, i dont see another approach that would be preferable here..
I would throw the exception in the method, unless this confuses the compiler.
private void throwMyException(final CustomErrorData errorData) {
... some info gathering, parameterizing, etc...
throw new MyException(errorData);
}
throwMyException(errorData);
or
private MyException throwMyException(final CustomErrorData errorData) {
... some info gathering, parameterizing, etc...
throw new MyException(errorData);
}
throwMyException(errorData);
// or if the compiler complains
throw throwMyException(errorData);
I'd separate the two concerns. Your class knows how to info gather, but shouldn't have to know about the exception (the user of that info).
First define a method to create a CustomErrorData instance:
private CustomErrorData createCustomErrorData() {
// info gathering
return new CustomErrorData(something);
}
Then define a constructor for the exception that uses a CustomErrorData:
public MyException(CustomErrorData errorData) {
// save it as a field
}
then
throw new MyException(createCustomErrorData());
where you need it.
This also allows you to use CustomErrorData for something else, perhaps logging, displaying to the user, whatever.
In my unit test, I test a method for an expected RuntimeException and I want to distinct those thrown by my component from ones thrown by the code called in the method.
Creating a custom exception type is unnecessary and does not solve the problem if the method throws the same exception type but for different reasons, e.g. InvalidArgumentException.
Looks like the only way to tell them is the message or the error code. Because the message can be changed during development, the error code seems the only reliable option.
What is the best practice for creating of system of error codes so they don't conflict with ones of external packages, eg. third party libraries?
Creating a custom exception type is unnecessary and does not solve the
problem if the method throws the same exception type but for different
reasons, e.g. InvalidArgumentException.
Why do you think it's unnecessary? This is what you should do. Derive your own custom exception classes, throw their instances from your code and catch them outside (in your unit tests). The catch statement can be repeated in anticipation of multiple different exception classes:
try {
// something
} catch (MySpecificException e) {
// you know that your code threw this
} catch (Exception e) {
// this is coming from somewhere else
}
--Edit--
Sorry, I didn't see the java tag. Even though the following example uses PHP constructs, the principles should still apply.
--Original--
I use custom exception codes in only a few, very specific cases, and I store these codes in a custom exception class which extends the default exception class. They are stored in the class as constants, as the value doesn't really matter, but the context does.
Consider:
class CoreLib_Api_Exception extends Exception
{
const EXCEPTION_FORMAT = '%s (%s): %s';
const CODE_FILE_DNE = 100;
const CODE_DIR_BASE_EQUALS_REMOVE = 101;
const CODE_XML_READER_UNABLE_TO_OPEN = 200;
const CODE_XML_READER_UNABLE_TO_READ = 201;
}
// Example usage
class CoreLib_Api_Reader
{
protected function getReader()
{
$reader = new CoreLib_Api_Xml_Reader();
if (!#$reader->open($this->getFileUri())) {
$e = new CoreLib_Api_Exception(sprintf('Could not open %s for parsing', $this->getFileUri()), CoreLib_Api_Exception::CODE_XML_READER_UNABLE_TO_OPEN);
throw $e;
}
}
}
// Calling code
try {
$reader = CoreLib_Api_Reader();
$reader->setFileUri($fileUri);
$reader->getReader();
} catch (Exception $e) {
// If code is anything other than open, throw it
if ($e->getCode() !== CoreLib_Api_Exception::CODE_XML_READER_UNABLE_TO_OPEN) {
throw $e;
}
$e = null;
$reader = null;
}
By using the exception code, I can check to determine if the reader is unable to open the file, if so ignore the exception and move on, otherwise throw the exception and break the flow.
And if one of my exception codes collides with a third party exception code, it doesn't matter, as I mentioned before, using constants, the context will dictate which code I want to match on.
I test a method for an expected RuntimeException
I think this is a mistake. A RuntimeException should be used only for indicating bugs in the code that the code itself can detect. Testing should test only for specified (defined) behaviour. But when there is a bug in some code, its behaviour is undefined (who knows where the bug could be or what it might do). So there is no point in trying to specify what RuntimeExceptions some code should throw; that is like specifying how the code should behave "in the presence of a bug". Throwing particular RuntimeExceptions with particular messages should be seen as a courtesy to the maintenance programmer (who is likely to be you).
What I am trying to do feels counter intuitive, but Java keeps surprising me all the time, so I give it a shot.
I am implementing an application with the help of the ESAPI library. This library provides its own exceptions. In addition to the well known exception behavior those exceptions do things like automatic logging with log4j and providing information to an intrusion detection module.
Now I want to use these features in all parts of my application. Anytime a method of mine throws an exception, I don't throw a normal exception but a selfmade exception that extends from the new EnterpriseSecurityException. Works like a charm.
But what can I do if I use a method, that throws a normal exception? Let's say I want to read a file using an java.io.FileInputStream? It cannot find the file and throws a FileNotFoundException. Unfortunately the FileNotFoundException does not provide the features of my own Exceptions, because it does not extend the EnterpriseSecurityException.
Is there any trick in Java to change the exceptions a method throws? It sounds strange to me as I write this, but maybe someone can come up with a solution. The only idea I had so far is catching the normal exception, extract the relevant information, and build a new exception with it. But this seems pretty crude...
Catch the exception and throw a new one that extends from EnterpriseSecurityException and pass the old exception to the new one to chain them together.
try {
...
} catch (FileNotFoundException e) {
throw new CustomEnterpriseSecurityException(e);
}
By chaining the exceptions you won't lose the stack trace from the original exception.
You can do this. Just catch the original exception and throw an appropriate exception you defined yourself and which extends EnterpriseSecurityException. Ensure that you chain the exceptions so that the stacktrace does not get lost.
For example with your file open example:
try {
//open file
} catch (FileNotFoundException e) {
throw new YoureCustomException("This is your message", e);
}
May be you can do like this:
try{
// file operations
}catch(FileNotFoundException e){
throw new MyCustomeFileNotFoundException(e);
}
Create your exception version for predefined exceptions and when you get any predefined exception in catch throw your defined exception.
A technique I've found very useful is to chain exceptions by using the Exception(Throwable cause) constructor as the superclass constructor. That way, you don't lose any of the stack trace, but can provide custom handling in your own class (which can look at the cause with the getCause() method if it wishes). For instance:
try{
//do something
}
catch(FileNotFoundException e){
throw new MyFileNotFoundException(e);
}