Is it possible to create something like an event in java which will be triggered if an Exception was thrown?
I want to make something like a exception tracking system which sends all Exception to a central server.
Is this possible or do I have to call a method on myself within every catch block?
The recommended way to handle this would be with logging (for example SLF4J and Logback). You can configure loggers to send the messages to a centralized logging server, but you still need to manually log the exception and if applicable, handle it.
If you were hoping for an automagical way to just forget about exceptions, that's not really possible. Exception handling is not as easy as it may seem, if you intend to make your applications robust and easily debuggable.
A good additional "trick" is to use Thread.setDefaultUncaughtExceptionHandler() to provide a final fail-safe. Its only job should be to log any exceptions that aren't handled elsewhere. However it should happen only in case there's a massive failure and the stacktrace might otherwise be lost. If it's being invoked just because some input was of the wrong format, your design and code is of poor quality.
Related
I use KafkaBolt in Storm to publish messages to various Kafka topics. I want to put logging and metrics around the publishing logic so I can create alerts around any exceptions that might be thrown when there's a publishing failure. Exposing those exceptions is done through a Callback function that's passed into KafkaProducer.send(), which is executed after publishing succeeds or fails.
The problem is that KafkaBolt completely encapsulates its KafkaProducer so there's no way to inject a custom Callback, so if I want to see any errors I have to look in the Storm UI. I've worked around this by creating a wrapper for KafkaBolt. This wrapper will, in turn, wrap the OutputCollector passed into KafkaBolt.prepare() in a custom OutputCollector that overrides the behavior of OutputCollector.reportError(). I can then add my own logging and metrics reporting code there and then have it call the original method.
This solution seems perfectly adequate for what I need, but it seems odd that KafkaBolt makes it so difficult to programmatically access those exceptions. I was wondering if maybe I was missing something obvious and if there was a better way to do this.
I don't think you're missing anything, you're likely just the first person with this need. Someone has to hit this issue and decide to fix it :)
If you'd like to make changes to the bolt to support custom error handling (e.g. by allowing the user to provide a callback as you suggest), you can raise an issue at https://issues.apache.org/jira/projects/STORM/issues and make a PR against https://github.com/apache/storm/pulls. You're of course also welcome to only raise the issue, someone else might see it and decide to fix it, but contributing the fix yourself would likely be faster.
edit: You can find the bolt code at https://github.com/apache/storm/blob/master/external/storm-kafka-client/src/main/java/org/apache/storm/kafka/bolt/KafkaBolt.java
Is it possible to expose sensitive application or system information via Java Exceptions when trust boundaries cross?
I mean, not just theoretically but if that happens in real environment.
e.g. java.io.FileNotFoundException might tell the caller about my application's file system structure etc .
java.util.ConcurrentModificationException
might give info about non-threadsafe classes of my app.
Can this situation be handled in any other way than the below two?
Use Sysouts ( with only a customized message ) instead of throwing exceptions for codes which are supposed to be accessed by others?
If its mandatory to throw exception, sanitize your messages and then throw exception
I am also wondering if point # 2 is completely avoidable and there would not be any mandatory situations for throwing exception.
My question is not about any specific application but programming practice in general ( where inter - application communication is needed in large enterprises like two different Banks etc ).
The most common way of exposing sensitive information is to give the user (client) of the program a stack trace.
A stack trace is useful for programmers debugging a problem, and not to anyone else. So logging code should not output stack traces as a matter of course. It should output them only when an exception indicates a bug in the program. And it should output them where they can be made available to a programmer, but to as few others as possible.
If a program has a log file invisible to normal users of the program but visible to administrators (as is the case with servers), that is an appropriate place to log stack traces.
Similarly arguments apply about other sensitive information.
Although your question is entirely about security concerns, this can be considered too as a user experience (user interface) issue: the messages you give to the various users of the program should be appropriate for those users, and should provide them with information that is useful to them, without extraneous information that could confuse them. In particular, the message text of an exception should not be reported to users (but should be include as part of any stack trace).
For a client-server program, the clients have no interest in the details of why the server failed to process a request sent by the client. They need to know that the request did fail. If the request failed because of a problem with the server, rather than a faulty request by the client, they need to know that is the case, so they can contact the administrators to fix the server. If the request failed because the client sent a faulty request, the client should be told that, with a description of what was faulty about the request, so the client can send a corrected request.
Also, beware that not all exceptions indicate a problem that some user must be told about. If the program automatically handles the condition signalled by an exception, in many cases there is no need to tell the user at all about the condition signalled by the exception.
I am writing a wrapper around the DefaultHttpClient to handle some of the error-prone configuration options.
For example I will pre-configure everything to handle UTF-8 properly and to shutdown the connection cleanly.
When a non-200 is returned, I thought about the client registering a handler for a specific status code and then calling it.
I would provide some default handlers to take care of simple cases.
Is this a good pattern for a clean API? If I throw exceptions, the client has to handle cases which might not happen at all as I would have to throw an exception per possible HTTP status code (or most).
The thing I like about handlers is that I can provide a couple of 'default handlers' which might be overwritten...
I'd like to hear your input and maybe get some more creative ideas.
Cheers
Currently, accepted practice for Java APIs is to employ unchecked exceptions, so client won't need to change it's internal code just to accommodate API's exceptions into client's codebase.
Instead, if you use unchecked exceptions, you'll save your code unchanged except the places where you really need to handle exceptions.
Here're slides about Robert Martin's "Clean code" book which talk about error handling best practices: slides.
I wouldn't create a different exception for each http error code. At most create one or two general exceptions and store the exact error code as part of the exception. That way if the client code just wants to log or ignore them it can, or it can get more details based on the error code.
My application uses some third-party libraries. I need to log some exceptions that occur inside lib (e.g. exceptions about read file), but these exceptions are caught in the same library.
Is there some way I can log these exceptions myself, even if they're not logged by the library?
Look at AspectJ. You can write an advice around construction (and maybe even thrwoing) of the FileNotFoundException. Be advised though, that it will log every time the the pointcut is reached. With some expertise you will be able to control it.
EDIT: Dave Newtwon pointed at at this example which shows how easy it is to do this once you get the hang of it.
I’ve been surprised by how hard it is to find best practices for this on the web since it must be such a common problem.
App is based on Java 1.5 – JSF 1.2 with Faclets, Seam, JPA, Hibernate. Some Web Service calls. Some JMS.
I’m after general recommendations for Exception handling. There are roughly 3 approaches I’ve seen used but I’ve never been that sure which one is better. Assuming you can’t recover from an error do you:
1) Log the error when it occurs and re-throw it?
2) Log it when it occurs and throw some sort of generic exception?
3) Let it bubble up and then handle it in a generic exception handling servlet or similar.
I’ve tended to use option 2 on previous systems where the architecture has been fairly simple – an adaptor layer talking to various 3rd party systems throws and adaptor exception if it gets an error back and so on. We can display a nice clean message to the user on the screen and keep the details in a log. Here though the architecture is a lot more complex and I’m wondering how well it would work in practice. So I’m interested to know what you prefer and why.
Assuming you can’t recover from an error...
Assuming this error is not a functional error, I log the error and wrap the exception in an (custom) unchecked exception and let the framework/container handle it (so option 2).
I like to do it his way because:
I like to use container managed transactions and I want the container to do its job (i.e. rollback any transaction) so throwing a runtime exception is the way to go.
It minimize the exception handling work.
It make the reporting to the user easy to handle in a generic way.
If it's a functional error (i.e. an alternative flow in a use case), I log the error and wrap the exception in a (custom) checked exception because I want the caller to handle it specifically as the problem is part of the use case.
In both case, I use a root exception for each hierarchy, namely TechnicalException and FunctionalException.