Custom Java exception printing when thrown - java

I want to design it such that whenever one of my custom exceptions is thrown, it automatically prints the stacktrace to a file. Is there a method I can override to accomplish this? Doing this would help to reduce a noticable amount of code in my project.

You can have your custom exceptions inherit from RuntimeException, then set the UncaughtExceptionHandler on the relevant Threads to look for your exceptions and handle them however you like.

The stacktrace is available as soon as you call the constructor of your exception. You can't react to the event of being thrown, but you can write the stacktrace inside your constructor.
If you have a common exception class that's the base of all your custom exceptions then you could do all this in its constructor.

Is there a method I can override to accomplish this?
Yes, the printStacktrace() method.
You can create a base class for your exceptions and them call to an "internal" print that would be redeirected to your file.
You can use a Logger and have that specific logger pointing to the file you desire ( and change it, disable it , re-enable it, etc when you need to )
Something along the lines:
class MyStackTrace extends Throwable {
public void printStacktrace() {
super.printStracTrace();
internalPrint();
}
private void internalPrint() {
StringWriter sw = new StringWriter();
printStackTrace( sw );
Logger logger = Logger.getLogger("exceptions");
logger.warning( sw.toString() );
}
}

I can'r help you print a stack trace when an exception is thrown. But it's easy enough to do when the exception is constructed - Just include the printStackTrace() in your custom exception's constructor.

In general, this is not a great idea to log on every exception creation. The catcher should really decide what is the best handling of an exception. Also overriding the method in exception and logging to a file breaks the general contract around exception.
On a side note, you may discover some horrible performance problem related to logging at later stage. Given overriding happens in a central place you will have hard time fixing this.
If you still want to log while throwing the exception then the better solution is to use/create a utility class like Throwables. Call the code as Throwables.logAndThrow(new CustomerException(...)), same one line of code but flexible for the long term. logAndThrow could be as simple as, using the logger technique of previous poster:
public static void logAndThrow(Throwable t) {
logger.warning(t);
throw t;
}

Related

Java, default exception messages

Given the following:
public abstract class Test {
public static void main(String[] args) {
int[] testArray = {6, 3, 2};
System.out.println(testArray[3]);
}
}
when I run the program I get:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at Test1.main(Test1.java:5)
In this case the JVM displays the index that is out of bounds i.e. 3.
This specific example aside, given that I choose not to catch an exception in a program's code:
How can I find out, for any exception, either checked or unchecked, what the default message would be that the JVM would display?
For a custom exception class that I write myself, and for an object of this class that I generate in my code using the 'throw' keyword (but, again, choose not to catch), can I set up a default message that the JVM would display?
How can I found out, for any exception, either checked or unchecked, what the default message would be that the JVM would
display?
As you might already suspect, the answer is "in general, you can't". Most of the time, the message is set from one of the constructors of the exception that takes a string message. If you're lucky, the message will be meaningful and provide useful information. Otherwise, as is common practice, the semantics of the exception will reside essentially in its class name and in the associated Javadoc. Also consider that exception messages are often localized.
For a custom exception class that I write myself, and for an object of this class that I generate in my code using the 'throw' keyword
(but, again, choose not to catch it), can I set up a default message
that the JVM would display?
That's entirely up to you. You could setup a default message in the default constructor like this:
public class MyException extends Exception {
public MyException() {
super("my default message");
}
public MyException(String message) {
super(message);
}
}
There is Thread.setDefaultExceptionHandler, all the uncaught exceptions will go there, so you can provide your own exception handler as an argument to that method somewhere in the beginning of your program.
I think, you can also construct any exception yourself and see the message as follows
new IOException().getMessage()
though probably the message in that case will be empty, I didn't try
I am only able to answer your second question.
In your Exception class (which should derive from java.lang.Exception) add (overwrite) the constructor accepting a String as an argument. Pass the message you want your thrown exception to have as a String to the new constructor et voilà → you got a personalized message for your exception. If you need a default message, just use this constructor from within the default one. Hope that helps.
Any exception that is of type or extends runtime exception is unchecked exception. Rest are checked exception.
You just need to extend runtime exception then you need not handle the exception that is thrown. And you can print default message for that exception by ovveriding getMessage method.

Why doesn't java.lang.ExceptionInInitializerError have a constructor with both message and cause?

I use java.lang.ExceptionInInitializerError to rethrow caught exceptions in static initialisation blocks. I noticed it is not possible to construct with both a message and a cause; only one or the other.
Is there a good reason why?
What alternatives can you suggest for rethrowing checked exceptions as unchecked exceptions from a static init block? Ex: Rethrow as java.lang.RuntimeException which allows both message and cause.
UPDATE: Clarified #2 and added sample code.
public class Sample {
private static final String _FILE_PATH = "blah/blah/blah";
static {
try {
FileReader in = new FileReader(new File(_FILE_PATH));
}
catch (FileNotFoundException e) {
// Option A: Without context message
throw new ExceptionInInitializerError(e);
// Option B: With context message
String msg = String.format("Failed to open file for reading: '%s'", _FILE_PATH);
throw new RuntimeException(msg, e);
}
}
}
Ref: Why doesn't Java allow to throw a checked exception from static initialization block?
As documented here, there is a constructor ExceptionInInitializerError(Throwable thrown), which you probably should be using instead: it conforms to standard exception chaining, which preserves the stack trace and does other useful stuff (see a sample chained-exception output).
Edit
As noted in this answer to the question you linked to: it is forbidden to allow a checked exception to fall out of a static block; unchecked exceptions are fine, but cannot be caught anywhere, unless one is doing manual dynamic class-loading with Class.forName (very uncommon).
This translates to "good luck catching anything you throw in a static initializer". Basically, whatever exception you construct and throw, it won't be much use.
You want to throw an exception with both a message (that you write) and the exception itself. I like to do the same, providing context for the error and the exception. I would throw an Exception (or an instance of an Exception class that extends Exception or a sub class), not RuntimeException since you probably want the exception to be checked. Right?
Generally speaking you should throw checked excpetions in cases where your system could potentially recover (at a higher level) from an exception and runtime exceptions (unchecked) when the system cannot. (James Gosling's view)
It's an Error. Generally errors are what an application shouldn't even try to catch and recover from.
As for why it doesn't have a constructor with both the message and cause, it's probably because the developers of that class didn't deem it necessary since the main purpose of that class is to let you know "oops shit happened bro, can't recover..."
Personally I think that one of those is enough to identify the error.

Record instantiation of java.lang.Throwable transparently [duplicate]

How can I detect when an Exception has been thrown anywhere in my application?
I'm try to auto-magically send myself an email whenever an exception is thrown anywhere in my Java Desktop Application. I figure this way I can be more proactive.
I know I could just explicitly log and notify myself whenever an exception occurs, but I'd have to do it everywhere and I might(more likely will) miss a couple.
Any suggestions?
You probobly don't want to mail on any exception. There are lots of code in the JDK that actaully depend on exceptions to work normally. What I presume you are more inerested in are uncaught exceptions. If you are catching the exceptions you should handle notifications there.
In a desktop app there are two places to worry about this, in the event-dispatch-thread (EDT) and outside of the EDT. Globaly you can register a class implementing java.util.Thread.UncaughtExceptionHandler and register it via java.util.Thread.setDefaultUncaughtExceptionHandler. This will get called if an exception winds down to the bottom of the stack and the thread hasn't had a handler set on the current thread instance on the thread or the ThreadGroup.
The EDT has a different hook for handling exceptions. A system property 'sun.awt.exception.handler' needs to be registerd with the Fully Qualified Class Name of a class with a zero argument constructor. This class needs an instance method handle(Throwable) that does your work. The return type doesn't matter, and since a new instance is created every time, don't count on keeping state.
So if you don't care what thread the exception occurred in a sample may look like this:
class ExceptionHandler implements Thread.UncaughtExceptionHandler {
public void uncaughtException(Thread t, Throwable e) {
handle(e);
}
public void handle(Throwable throwable) {
try {
// insert your e-mail code here
} catch (Throwable t) {
// don't let the exception get thrown out, will cause infinite looping!
}
}
public static void registerExceptionHandler() {
Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler());
System.setProperty("sun.awt.exception.handler", ExceptionHandler.class.getName());
}
}
Add this class into some random package, and then call the registerExceptionHandler method and you should be ready to go.
The new debugging hooks in Java 1.5 let you do this. It enables e.g. "break on any exception" in debuggers.
Here's the specific Javadoc you need.
Check out Thread.UncaughtExceptionHandler. You can set it per thread or a default one for the entire VM.
This would at least help you catch the ones you miss.
If you're using a web framework such as Spring then you can delegate in your web.xml to a page and then use the controller to send the email. For example:
In web.xml:
<error-page>
<error-code>500</error-code>
<location>/error/500.htm</location>
</error-page>
Then define /error/500.htm as a controller. You can access the exception from the parameter javax.servlet.error.exception:
Exception exception = (Exception) request.getAttribute("javax.servlet.error.exception");
If you're just running a regular Java program, then I would imagine you're stuck with public static void main(String[] args) { try { ... } catch (Exception e) {} }
If you are using java 1.3/1.4, Thread.UncaughtExceptionHandler is not available.
In this case you can use a solution based on AOP to trigger some code when an exception is thrown. Spring and/or aspectJ might be helpful.
In my current project I faced the similar requirement regarding the errors detection. For this purpose I have applied the following approach: I use log4j for logging across my app, and everywhere, where the exception is caught I do the standard thing: log.error("Error's description goes here", e);, where e is the Exception being thrown (see log4j documentation for details regarding the initialization of the "log").
In order to detect the error, I use my own Appender, which extends the log4j AppenderSkeleton class:
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.spi.LoggingEvent;
public class ErrorsDetectingAppender extends AppenderSkeleton {
private static boolean errorsOccured = false;
public static boolean errorsOccured() {
return errorsOccured;
}
public ErrorsDetectingAppender() {
super();
}
#Override
public void close() {
// TODO Auto-generated method stub
}
#Override
public boolean requiresLayout() {
return false;
}
#Override
protected void append(LoggingEvent event) {
if (event.getLevel().toString().toLowerCase().equals("error")) {
System.out.println("-----------------Errors detected");
this.errorsOccured = true;
}
}
}
The log4j configuration file has to just contain a definition of the new appender and its attachement to the selected logger (root in my case):
log4j.rootLogger = OTHER_APPENDERS, ED
log4j.appender.ED=com.your.package.ErrorsDetectingAppender
You can either call the errorsOccured() method of the ErrorsDetectingAppender at some significant point in your programs's execution flow or react immidiately by adding functionality to the if block in the append() method. This approach is consistent with the semantics: things that you consider errors and log them as such, are detected. If you will later consider selected errors not so important, you just change the logging level to log.warn() and report will not be sent.
In this case I think your best bet might be to write a custom classloader to handle all classloading in your application, and whenever an exception class is requested you return a class that wraps the requested exception class. This wrapper calls through to the wrapped exception but also logs the exception event.
I assume you don't mean any Exception but rather any uncaught Exception.
If this is the case this article on the Sun Website has some ideas. You need to wrap your top level method in a try-catch block and also do some extra work to handle other Threads.
Sending an email may not be possible if you are getting a runtime exception like OutOfMemoryError or StackOverflow. Most likely you will have to spawn another process and catch any exceptions thrown by it (with the various techniques mentioned above).
There is simply no good reason to be informed of every thrown exception. I guess you are assuming that a thrown exception indicates a "problem" that your "need" to know about. But this is wrong. If an exception is thrown, caught and handled, all is well. The only thing you need to be worried about is an exception that is thrown but not handled (not caught). But you can do that in a try...catch clause yourself.

Is "throws Throwable" good practice

In the past I'd read tons of code with methods like:
public Object doSomething() throws Throwable {
...
}
Is it common practice to do that?
What are pros & cons?
throws Trowable seemed to me like the "Agent Orange" way of getting the Exception- matter done
EDIT
Handle expected Exceptions in the Method
Throw unexpected Exceptions (one by one)
Don't care of Errors
Is that the way to go?
You should not throw Throwable. Here's why.
Throwable is the top of the hierarchy of things that can be thrown and is made up of Exceptions and Errors. Since Errors by definition arise from unsalvagable conditions, it is pointless to include them in your method declaration. That leaves just Exception.
You should declare your method with throws Exception instead.
Note that the narrower the range of throws the better.
Declaring your method to be throws Exception is ok if your method doesn't generate the exceptions, but instead calls other code that is declared as throws Exception and you want exceptions to percolate up the call stack.
If your method is the generating the exception, then declare a narrower range, eg throws IOException, MyProcessingException, etc
That's a loaded question. This isn't so much about exception handling as it is about code readability.
It depends where you get your code samples from. Professionals prefer to be more specific when throwing out of a method. The main reason is that it keeps your APIs more readable. For example, if your method throws Throwable, that basically means anything could happen and your method doesn't want to deal with it, no matter what. But really, only a limited number of things could happen:
Whatever checked exceptions resulting from other calls you are making in your method
Whatever checked exceptions you are throwing on purpose based on your own assertions
Whatever unchecked exception you didn't plan for
Errors (java.lang.Error) that are more global to the JVM and the environment
By specifically stating the exceptions you want to throw, you are telling the users of your API about what they should beware of. For example, when you use InputStream, you'll notice most methods throw at least java.io.IOException, which gives you some useful information about what you should watch for.
When coding, as a general rule, you want to try to keep your APIs as expressive as possible. You've got essentially one line of code to show the public API of a method (i.e. its signature, annotations too I guess), so you want it completely expressive (return type, name, parameters, but also the thrown exceptions).
As far as catching the throwables and printing the stack trace, I'd say that you should not catch the exception unless you can do something about it. Instead, let it roll up the call stack until some class catches it to do something about it. Sometimes, it may roll all the way up to your main class, which I guess would have to catch it and print the stack trace as last resort. Basically, if you can't act upon the exception, then let it go up the call stack. Also it is extremely rare that you find yourself in a situation where you should silence an exception (i.e. catch it but do nothing about it). That's usually inviting problems when comes time to troubleshoot issues.
Here is a fun but interesting article around misuse of exception handling in general.
In some rare cases it is acceptable to throw Throwables. For example, #Around advices in Spring AOP are usually declared to throw a Throwable.
The following example is copied verbatim from Spring AOP docs:
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.ProceedingJoinPoint;
#Aspect
public class AroundExample {
#Around("com.xyz.myapp.SystemArchitecture.businessService()")
public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
// start stopwatch
Object retVal = pjp.proceed();
// stop stopwatch
return retVal;
}
}
Why is doBasicProfiling declared to throw a Throwable? Because the original method (i.e. the execution join point), might throw an Error, RuntimeException, or a checked exception. So it only makes sense to declare doBasicProfiling to throw a Throwable.
Functionally, it is equivalent with throws Exception, since errors are unchecked.
I see no reason to declare a method to throw Throwable. However, this doesn't mean that catch and printStackTrace is a good alternative.
Usually, you want to catch throwables where you can do something sensible with them.
Code that throws a throwable you don't expect should explode gloriously, so you can see the error and fix the bug.
Is it common practice to do that?
In the JDK it is rare. This is mostly used when it is not clear how to handle checked exceptions.
What are pros & cons?
The pros is that you get your code to compile without worrying about checked exception.s
The cons is that exception you should be handling are being ignored.
Isn't it better to catch and printStackTrace()?
Unhandled exception are usually printed anyway so catching them doesn't help much.
You should catch an exception when you can add some value by doing so and add the exception to the throws clause when you can't.
It is really debatable matter.
Having method throwing too many exceptions will result in lot of error handling code. Some times it is not intended.
But because I don't like too many exception in signature does not mean that Lets use Parent of all exceptions and we are done!! It will not work.
What one can do is categorise exceptions such as BusinessException,ServiceException so that if you have a business rule which says that minimum balance in account can not be less than say 100$ then InsufficientBalance exception will be generated which will be child of BusinessException
so you method will be like
public Object doSomething() throws BusinessException {
if(!hasMinimumbalance())
{
throw new InsufficientBalance(ErrorCode);
}
}
What this will do is club related exceptions together and whenever API user wants to detect exception specific error then he can do it, else generic error handling is possible.
The core point here is on the UI you should display to the user that You have run out of balance and you can not withdraw money
You can say on the larger aspect to display human readable form of error it is really necessary to have separation of exceptions.
Are you asking about Throwable specifically? If so, then it's not good practice. It doesn't provide any useful information to class (method) user.
Throwing (and catching) Throwable (or Exception) is generally bad practice because it 'blankets' any specific exceptions you might want to catch. Then you would have to resort to ugliness like below:
public void myMethod() throws Throwable {
if (x) {
throw new MyException1();
}
if (y) {
throw new MyException2();
}
}
public void callingMethod() {
try {
myMethod();
}
catch(Throwable t) {
if (t instanceof MyException1) {
// handle exception 1
}
else if (t instanceof MyException2) {
// handle exception 2
}
else {
// handle other exceptions
}
}
}
Which is error prone (and flagged by CheckStyle as a code violation). It is much preferrable to have code like this:
public void myMethod() throws MyException1, MyException2 {
if (x) {
throw new MyException1();
}
if (y) {
throw new MyException2();
}
}
public void callingMethod() {
try {
myMethod();
}
catch(MyException1 e) {
// handle exception 1
}
catch(MyException2 e) {
// handle exception 2
}
}
Handling an exception just by calling printStackTrace() is usually not a good idea. printStackTrace() sends the stacktrace to standard error, which may not be read at all. A better option is to use the application's logging facility (like log4j) to report the exception. Even then, just logging it might no be enough.
My rule of thumb is:
If you can handle an exception locally, do so. For example when parsing a String as an Integer you could catch the NumberFormatException and return a default value:
prvate int parseAmount(String amountValue) {
int amount;
try {
amount = Integer.parseInt(amountValue);
}
catch(NumberFormatException e) {
// default amount
amount = 0;
}
return amount;
}
If you cannot handle an exception locally, consider if you should expose the exception type that is being thrown. If this type is some obscure (implementation-dependent) type, then wrapping it in your own generic exception type is probably a good idea:
private Customer getCustomer(int customerId) throws ServiceException {
try {
return customerService.getCustomer(customerId);
}
catch(CustomerServiceSpaghettiTangledException e) {
throw new ServiceException("Error calling the customer service", e);
}
}
Here 'ServiceException' is a subclass of Exception created by you. Spring also offers an exception hierarchy specifically for this purpose.
By wrapping the exception you hide the implementation details, making your service layer much simpler to use.
If you decide to throw an exception from your method, you will need to handle it 'higher up' in the callstack. This can be a generic error page in your web application stating that something went wrong and possibly providing an error message or code. In some cases the higher level code can attempt a retry or possibly an alternative way to obtain the required result.
The only use case I can think of would be for test code like unit tests. But Adam's counterpoint still stands "If so, then it's not good practice. It doesn't provide any useful information to class (method) user."

Java, return new MyException: anti-pattern?

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.

Categories

Resources