I use exceptions to flow control a lot, but I have a strange feeling that I am doing something wrong. Is it a good practice to write something like code shown bellow?
public static void main(String[] args)
{
try
{
methodA();
}
catch (Exception ex)
{
handleException(ex);
}
}
public static methodA()
{
methodB();
}
public static methodB()
{
if(someConditionIsNotMet)
{
throw new RuntimeException("Some Condition Is Not Met");
}
}
I use exceptions to flow control a lot
Throwing specific and functional exceptions to indicate a functional issue during the workflow is not bad itself.
It is not the single way to do it but it is a valid way.
Another way relies on methods that returns boolean and testing the returned value.
Personally, I don't use this way as I found it rather verbose, error-prone (we have not to forget to test the returned boolean) and less expressive (it has only two values: true and false) than an exception (it may have as many as required).
Suppose that method B has to check something and that if the check fails the processing should be stopped and the client notified of the issue, it would be totally valid to use exceptions for this purpose.
Now, it would make more sense to make the exception a specific exception rather than Exception.
Otherwise how the client could interpret the exception meaning ?
The exception could be a workflow exception but it could be also any exception thrown at runtime for another reason such as a NullPointerException.
You want to handle workflow exceptions in a specific way while you will not apply a specific processing to other thrown exceptions.
For example you could write something as :
public static methodA()
{
methodB();
}
public static methodB(){
if (!expectedDataFound()){
throw new DataNotFoundException("data xxx was not found");
}
if (!hasRights()){
throw new PermissionException("user xxx has not the rights for yyy");
}
}
Then from the client side, you have two ways.
Catching each exception individually or catching them in a common way (that is possible only if they make part of the same hierarchy).
Catching each exception individually :
public static void main(String[] args)
{
try
{
methodA();
}
catch (DataNotFoundException ex)
{
handleDataNotFoundException(ex);
}
catch (PermissionException ex)
{
handlePermissionException(ex);
}
}
Catching exception globally:
public static void main(String[] args)
{
try
{
methodA();
}
catch (WorkflowException ex)
{
handleWorkflowException(ex);
}
}
I think you are too harsh on yourself with saying that you "use exceptions to control flow". It is an antipattern to use exceptions for control flow, but in your example you do not.
Let's say that you have a method that sets the age for the user, and of course if the caller provided negative number, you should not complete the action. So a very reasonable way to ensure that, would be:
public void setAge(int age) {
if(age <0) {
throw new InvalidArgumentException("Age has to be zero or positive number");
}
}
If you prefer not to use exceptions maybe you can use features of the language such as Optionals or create response structure that handles both success and errors. For example, lets say you have a method that retrieves employees
public EmployeesOverview getEmployees() { ... }
Your response class could look like this:
public class EmployeesOverview {
private Ok ok;
private Error error;
class Ok {
private Set<Employee> employees;
}
class Error {
private String errorMessage;
}
}
So without throwing exception your method will provide clients with results or if there is a problem, the client will be informed about it.
I would separate flow control and exception handling. Flow control is meant for making sure statements are executed in correct sequence and under correct conditions. This must be determined at design time. Exception handling is meant to handle unforeseen situations at run time. Exceptions are almost always due to external factors: time outs, no disk space, data errors...
Just my two cents.
Related
I'm trying to get into exception handling via custom exceptions.
I'm creating the class CustomExceptions and extending Exception as follows:
public class CustomExceptions extends Exception{
public CustomExceptions (String s) {
super(s);
}
However, rather than having to create multiple files for every custom exception I want, or bloating my main class file, I'd like to put all of my custom exceptions in this class and invoke them via a method
So let's say that I want to handle 2 situations: When the user tries to input a seat reservation, but the seat is already taken, and when the user tries to provide a ticket for someone outside of the age range.
Can I create 2 methods inside of the CustomExceptions class which invoke the constructor passing a custom message to it?
public void seatTaken(String s) {
String s = "The seat is taken, please choose a new one";
CustomExceptions(s);
}
public void notOldEnough(String s) {
String s = "User is not old enough for this movie.";
CustomExceptions(s)
}
}
Would this work? Or am I forced to create multiple custom exception files?
Generally custom exceptions should be defined in the top level. Because, almost universally, these exceptions are part of the interface of the package or module.
If the user cannot see them, then how are they going to catch them separately? And if you don't want to catch them separately, then why would you need separate classes?
However, if you must, you can include them into a class for which they are required:
public class SeatReservationSystem {
public static class ReservationFailedException {
... constructors taking a message ...
}
public static class SeatTakenException extends ReservationFailedException {
... constructors taking a message ...
}
public static class OutsideAgeException extends ReservationFailedException {
... constructors taking a message ...
}
....
}
After that you can create any method that returns them as required. Don't create methods that throw them as the compiler won't see those as exit points of the block you're in, and you'll get strange situations.
Here is some code to show what I mean:
// wrong
public static void throwRuntimeException() throws RuntimeException {
throw new RuntimeException();
}
// correct, but dangerous
public static RuntimeException createRuntimeException() {
return new RuntimeException();
}
public static void main(String[] args) {
String initializeMeOrThrowException;
if (new Random().nextBoolean()) {
// compiler doesn't recognize that the method always throws an exception
throwRuntimeException();
// this the compiler can understand, there is an explicit throw here:
// throw createRuntimeException();
// but this is the pitfall, it doesn't do anything:
// createRuntimeException();
} else {
initializeMeOrThrowException = "Initialized!";
}
// Compiler error for throwRuntimeException and createRuntimeException without throws:
// "The local variable initializeMeOrThrowException may not have been initialized"
System.out.println(initializeMeOrThrowException);
}
However, experience learns me that I forget the throws statement for the throw createException(...); method, and the stupid compiler doesn't warn me about that (even though the statement is utterly useless without it). So I try and not use either.
Note that I'm not certain if you should use exceptions for this. If your system is a reservation system, then refusing tickets is not that exceptional. Returning a ReservationResult makes more sense.
How I can scan my code and get all possible throws MyException errorCode's of execute() function?
Errors const:
public enum ErrorId {
OK(1),
REPORT_LIMIT(2),
NOT_UNIQUE_FIELD(3),
INCORRECT_PROPERTY(4);
private int id;
ErrorId(int id) {
this.id = id;
}
}
For example I have 'MyException' :
public class MyException extends Exception {
#Getter
protected final ErrorId errorCode;
public MyException(ErrorId errorCode) {
this.errorCode = errorCode;
}
}
And class with method:
public class MyClass {
public void execute() throws MyException {
//do something 1
...
if(isSomethingWrong1) throw new MyException(ErrorId.REPORT_LIMIT);
executeMethod2();
//do something N
if(isSomethingWrongN) throw new MyException(ErrorId....);
}
public void executeMethod2() throws MyException {
// ...
throw new MyException(ErrorId....)
// ...
}
}
I don't think there's an answer here that you'll like.
Reflection won't work in this case, because it's concerned with types, not values. The compiler can't help you here, either, because if the error code comes in through a variable, then at runtime, all bets are off -- the value could be any possible value of the type you're using. If you're using an enum for the code value, then you have a known list of all possible values, but you won't know which ones are actually used in any particular function without reading that function. A static analysis tool may be of use here, but you'd need to continue running it over time to keep this information up to date.
However, all is not lost. As I said in my second comment, you have another choice -- extract subclasses. Let's consider this definition of your Exception class.
public abstract class MyException extends Exception {
#Getter
protected final ErrorId errorCode;
public MyException(ErrorId errorCode) {
this.errorCode = errorCode;
}
}
It's the same as yours is now, but it's abstract. This class is open for extension. So we could create a subclass ReportLimitException like this:
public class ReportLimitException extends MyException {
public ReportLimitException() {
super(ErrorId.REPORT_LIMIT);
}
}
and another like this, for example:
public class DuplicateFieldException extends MyException {
public DuplicateFieldException() {
super(ErrorId.NOT_UNIQUE_FIELD);
}
}
Now, any given method can advertise which particular exceptions it uses via its throws clause. This is, in fact, why that clause exists.
public void execute() throws ReportLimitException, DuplicateFieldException {
//do something 1
//...
if(isSomethingWrong1) throw new ReportLimitException();
executeMethod2();
//do something N
if(isSomethingWrongN) throw new DuplicateFieldException();
}
At this point, if you advertise the exceptions explicitly, you'll have achieved your goal, at the cost of some potentially long throws clauses (which should actually be a hint to you that the method may be doing too much work anyway). Alternatively if you don't want to advertise every exception like that, you could also use your IDE's "find references" feature to locate every place where those exceptions are created (look for references to the constructors).
And the calling code doesn't even have to be aware of the change. It can continue using code like this:
try {
// stuff that might throw any of your exceptions
} catch (MyException ex) {
switch (ex.getErrorCode()) {
// handle the cases...
}
}
So I have a generated class (PartnerConnection) that provides DML operations to the SalesForce cloud platform. We were having issues where our long running integration process was failing due to connection issues with either SalesForce or the system running the code.
In order to solve this issue, I extended the PartnerConnection class with what I name an AdvancedPartnerConnection. The AdvancedPartnerConnection just overrides the methods of the PartnerConnection and wraps them with try/catch/retry logic.
#Override
public QueryResult query(String queryString) throws ConnectionException{
int attempt = 0;
ConnectionException lastException = null;
while(true){
if(attempt < maxAttempts){ //maxAttempts constant
if(lastException != null){
try {
//exponentially increase wait times
Long sleepTime =(long) Math.pow(sleepBase, attempt) * 300;
Thread.sleep(sleepTime);
} catch (InterruptedException e1) {
// something bad has happen, throw the connection exception
throw lastException;
}
}
attempt ++;
try{
//call super class method
return super.query(queryString);
}catch(ConnectionException e){
lastException = e;
}
}else{
throw lastException;
}
}
}
I've implemented this for a handful of the super class methods and the only difference is the method being called and its' parameters. It has become a real pain if I decided to change any of the retry logic as I want it to be consistent across all methods.
Does anyone have a way I could extract the retry logic into a separate class or method and maybe pass in the function call? I've done stuff like this in .NET but I'm not sure how to do it in java.
You basically want to capture all calls to all object methods and apply some logic to all of them.
You could create a Proxy and retry in the handler invoke method.
With this approach based on the method signature you decide what to do.
Another approaches could use AspectJ or any other AOP framework, but your use case is very simple to add that kind of dependencies, IMO.
If the class which you want to add some behaviour is not yours then this solution might not be the most elegant. But if you are willing to sacrifice some elegance to gain maintainability (since you are not replicating code) then you could:
class NotYourClass {
public void voidMethod() {}
public int intMethod(int n) { return 0; }
}
To create a proxy you must create an interface with all the methods of the class. This is the crappy part, but this do not add any dependency to your application.
interface YourInterface {
public void voidMethod();
public int intMethod(int n);
}
Next thing you need is an InvocationHandler that will contain the behavior.
class YourInvocationHandler implements InvocationHandler {
private final NotYourClass target;
public YourInvocationHandler(NotYourClass target) {
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
// Here you must look to the methods that are the ones that you want.
return method..invoke(target, args);
} catch (Exception e) {
// Retry?
method.invoke(target, args);
}
}
}
Please bear in mind that this is from the top of my head. But should be something along those lines.
If creating that interface is something unnacceptable for you then you can look at some AOP frameworks.
I am a little bit confused with exceptions in Java and when to use which particular style of implementation.
I used IllegalArgumentException as an example, but the main point I would like to address is when does one throw, extends or throw new exception?
Also as an additional point I have an assignment where I have to create a java class and the spec vaguely states that the constructor should throw an IllegalArgumentException so which one would be the best to use?
public class Test{
//when does one use this type of exception
public Test(String yourName) throws IllegalArgumentException{
//code implemented
}
//when does one use this type of exception
public Test(String yourName) extends IllegalArgumentException{
//code implemented
}
public Test(String yourName){
if(yourName.length() <= 0){
//why not use this type of exception instead
//and what happens when I use this type of exception
throw new IllegalArgumentException("Please Enter Your Name..!");
}
}
}
Thanks in advance.
When some Exception occurs, you have two ways of handling it: doing throws from the method or doing try-catch. The first one looks like this:
public class MyClass {
public void myMethod() throws IllegalArgumentException {
someOtherMethod();
}
}
In this case you know that someOtherMethod() can throw an exception and you don't want to handle it - you just pass it further. After that, the invoker of myMethod() should take care of the Exception.
But the second way is when you handle it by yourself:
public void myMethod() {
try {
someOtherMethod();
} catch (Exception e) {
System.out.println("You've got an exception!");
}
}
About throwing exceptions manually - you may suppose that you do it in someOtherMethod(). When you do throw new IllegalArgumentException("Please Enter Your Name..!"); the program stops with a message about this exception (unless you handle it in a try-catch way).
And at last, you extend some exception, when you create your own Exception class:
class MyException extends IllegalArgumentException {
...
}
In this case you may do throw new MyException(); in your code.
I'd advise you to read more about exceptions in Java to understand what is going on. You may start with this lesson.
To ensure that you don't end up creating exceptions which already have equivalent in the standard library, I normally have a peek at the documentation before creating new exceptions. Also, it's very easy to go crazy with really big exception hierarchies if you are not careful. Don't create new exceptions just because you think you need to throw one somehow; create one because a code somewhere down the call stack would be doing something useful/different with that exception.
public Test(String yourName) throws IllegalArgumentException
You normally never specify runtime exception in the throws clause though it might be helpful if you need this information to be part of the public API.
public Test(String yourName) extends IllegalArgumentException
This doesn't look right and isn't valid Java.
I would only create a new exception type when you need to. You need a new type when you expect the caller to have catch clause for your new exception.
you can create new exceptions just to be more descriptive but that is what I use the message for.
I'm looking to clean up the exception mess that is currently the code base I'm working on.
The basic setup is this.
I have an interface that is implemented by a lot of classes that looks like this:
public interface TerminalMessage<E> {
// Override for specific return data type.
public E send(TerminalStream stream) throws Exception;
}
These classes throw a lot of different exceptions, like IOException, InterruptedException etc.
As it is now, all I do is call getMessage() on the catched exceptions and relay this message to the ui-code.
This is not very nice since I sometimes get bogus messages displayed to the user and I catch unwanted exceptions.
I'm thinking of creating a custom exception class (TerminalException) that would wrap all these kinds of exceptions.
However I'm not sure where to do the wrapping, should the wrapping be done where the exception is first thrown (in the output stream for example) or in every send() method. The former has the advantage of not adding much code, but it makes more sense to me that a stream throws IOException rather than a TerminalException.
The above design also doesn't really solve the sometimes bad messages displayed to the user, so some tip on how to transform the thrown exceptions into something useful to the user would be great!
Thanks!
a custom exception is a very good idea if you have useful information in it like an error code.
just wrap everything with your TerminalException, but do not forget the cause
OR
use the first TerminalException thrown:
public class MyException extends Exception{
String errorMessage;
public MyException(String message, Exception cause){
super();
if(cause instanceof MyException){
// already wrapped
errorMessage= cause.getErrorMessage();
initCause(cause.getCause());
}
else{
// not my Exception
errorMessage=message;
initCause(cause);
}
ยด
}
}
Another option could be to use a Template Method Design Pattern and "control" the exeptions therein as follows:
public abstract TerminalMessage<E> {
public abstract E doSend(TerminalStream stream);
public E send(TerminalStream stream) throws Exception {
// do common stuff here
try {
doSend(stream);
}
// catch more specific exceptions first
// handle all the exceptions accordingly here, thus controlling
// in one central location what will be thrown externally
catch(Exception) {
}
}
}
This way the exception handling for all of the derived classes will be the same and and localized, and the derived classes wont have to do anything special.
From many designs I have tried, this is the final one which I happily use on some projects.
public enum ExceptionCodes {
IOException("ioexception", false),
UserNotFound("usernotfond", true);
private static final String BUNDLE_NAME = "SOME_bundle_name";
private final String bundleCode;
private final String isManagable;
ExceptionCodes(String bundleCode, String isManagable) {
this. ...
...
}
public String message() {
// eventually get locale from somewhere, for example some threadLocal
return SomeBundleResolver.resolve(BUMDLE_NAME, bundleCode);
}
public Boolean isManagable() {
return isManagable;
}
}
public class MyGenericException extends RuntimeException {
private final ExceptionCodes exceptionCode;
private final Throwable throwable;
public MyException(ExceptionCodes exceptionCode) {
this....
...
}
public MyException(ExceptionCodes exceptionCode, Throwable throwable) {
this. ...
....
}
public Boolean isManagable() {
return exceptionCode.isManagable();
}
public String getMessage() {
return (throwable == null) ? super.getMessage() : throwable.getMessage();
}
...
}
Point is that exception codes are managed at one place. You can add custom atributes to enum like error codes etc. One of the many problem with exceptions is that if you do not know how to handle exception at place it is unprobable you will know how to handle exception layer above. Then just two cases can occur. Either exception can be displayed in some format to user, or system has to crash in some gracefull way. Attribute isManagable is exactly about this. If exception si not managable system must go down. So the exception is handled just at top level of application in general error handler. This way you can prevent Exception explosion.