-
Notifications
You must be signed in to change notification settings - Fork 2
ApplicationException
- Each ErrorCode definition created by a developer must have a 1:1 relationship with a unique error message.
- Each component owner must maintain the error code list for his component.
Assuming the application is built out of several components, it is likely that every now and then some components may be found in an Error state.
In such a case the component should create an Application Exception and pass it a relevant predefined ErrorCode. To create an ErrorCode, simply instantiate the ErrorCode class supplied by the infrastructure.
The ErrorCode should be unique enough for a system engineer to be able to look it up in the error code list and understand what was the original problem.
The above should be true even when original application has been wrapped by other components. We still want the original cause to be clear as well as the component that got the original error.
It is assumed that if you extend ApplicationException you will also override the default constructors provided in it and call super() from them. Explicitly you must override this constructor:
public ApplicationException(final String message, final ErrorCode errorCode)
failing to do the above may change the flow of the application in certain cases like when using remote invocation.
The following API should be used for the first component that got an Exception:
//create the error code and pass it your component Id, and an int that is the code itself.
ErrorCode errorCode = new ErrorCode("My Comp ID", 111);
//create the application exception based on your custom message and the created error code.
ApplicationException exception = new ApplicationException("my custom message", errorCode);
throw exception;
In case Error state was burn due to another exception use this API
try {
//do something that caused an exception - E.g - an SQLException
}catch (SQLException exceptionCause){
ErrorCode errorCode = new ErrorCode("My Comp ID", 111);
ApplicationException exception = new ApplicationException("my custom message", exceptionCause, errorCode);
throw exception;
}
When another component catches the application exception thrown by the previous component, it must not create a new ErrorCode. The API to be used should be as follows:
try{
//call another component API that throws an exception
}catch (CompcustomApplicationException exceptionCause){
ApplicationException exception = new ApplicationException("my custom message", exceptionCause);
throw exception;
}
In the case described above the infrastructure will make sure the ErrorCode is updated in the newly created ApplicationException so we know it is the same ErrorCode all the way...
If compA uses compB, and compB create an Exception that extends ApplicationException that is called: "MyApplicationException", with an error code of: 123 - the log will look as follows:
2009/04/03 07:07:00.000 MyTest [1]: ERROR: com.cisco.oss.foundation.application.exception.ApplicationException:
[compB-123]
ERROR
from
compA
at com.comp.exception.TestException.testMessage(TestException.java:18)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:73)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:46)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:45)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: com.comp.exception.ApplicationException:
[compB-123]
ERROR
message
from
compB
at com.comp.exception.TestException.testMessage(TestException.java:14)
... 24 more
The main benefits are:
- Support transparent passing of original error cause to the highest component in the chain.
- Print this cause in the exception message output
- the error code will be printed to the log system using the
following notation:
[componentId-code] my custom error message
- the error code will be printed to the log system using the
following notation:
If needed you can use the RuntimeApplicatiobException to have the same capabilities of the above mentioned ApplicationException together with a RuntimeException paradigm.
Every entry point that responds to another system with an exception or Error Code (I.e. Soap Gateway) must expose a unified set of error message to the calling application. This means that in the entry point level there must be a catch for all Exceptions including ApplicationException and throw some sort of predefined exception that contains an error message which is familiar in the client.
Following is an example of such code:
try{
//call another component API that throws an exception
}catch (Exception exceptionCause){
//write code that explores the real cause of the exception.
CsutomException exception = new CustomException("my message known to the client");
throw exception;
}