0

A part of my program checks the current data with a specified date to see if it is before that date. If it is, I want to throw a TooEarlyException.

My TooEarlyException class(note that it currently is checked, but I am trying to decide if it should be checked or unchecked):

public class TooEarlyException extends Exception {
    private int dayDifference;
    private String message = null;

    public TooEarlyException(int dayDifference) {
        this.dayDifference = dayDifference;
    }

    public TooEarlyException() {
        super();
    }

    public TooEarlyException(String message) {
        super(message);
        this.message = message;
    }

    public TooEarlyException(Throwable cause) {
        super(cause);
    }

    public int getDayDifference() {
        return dayDifference;
    }

    @Override
    public String toString() {
        return message;
    }

    @Override
    public String getMessage() {
        return message;
    }
}

Here is my code that checks the dates and throws the exception if necessary(assume that today and dateSpecified are Date objects):

public void checkDate() throws TooEarlyException{
    //Do Calendar and Date stuff to get required dates
    ...
    //If current Date is greater than 4 weeks before the event
    if(today.before(dateSpecified)) {
        //Get difference of dates in milliseconds
        long difInMs = dateSpecified.getTime() - today.getTime();
        //Convert milliseconds to days(multiply by 8,640,000^-1 ms*s*min*h*days)
        int dayDifference = (int)difInMs/8640000;
        //Throw exception
        throw new TooEarlyException(dayDifference);
    } else { //Date restriction met
        //Format date Strings
        DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM);
        System.out.printf("Today Date: %s%n", df.format(today));
        System.out.printf("Event Date(Actual): %s%n", df.format(eventDateActual));
        System.out.printf("Event Date(4 Weeks Prior): %s%n", df.format(dateSpecified));
    }
}

How I call checkDate:

try {
    checkDate();
} catch(TooEarlyException e) {
    System.out.printf("Need to wait %d days", e.getDayDifference());
    e.printStackTrace();
    System.exit(1);
}

In this post, Gili says:

Checked Exceptions should be used for predictable, but unpreventable errors that are reasonable to recover from.

My question with this is in my case, this error would be considered predictable but unpreventable, but not recoverable from, as my program needs to be run within 28 days of a specified date(this is because the API I am using has a restriction that in order to get data for an event, it must within 4 weeks before the event starts). Essentially, if this error happens, I intentionally want the program not to be able to run.

Should I make this a checked exception, or an unchecked exception, keeping in mind that the program should not run if the Date restriction isn't met?

Robert Engle
  • 45
  • 1
  • 7
  • 2
    You're throwing an exception and catching it in the same method, which means you're using the exception for control flow. You shouldn't do that. See [Are exceptions as control flow considered a serious antipattern? If so, Why?](https://softwareengineering.stackexchange.com/q/189222/202153) – Andreas Aug 04 '18 at 23:48
  • @Andreas I changed my code so that I am not throwing an exception and catching it in the same method. Would the code now be considered correct? – Robert Engle Aug 05 '18 at 00:02
  • 1
    This still strikes me as something I wouldn't use an exception for, but if you truly want to program to hard-exit, then why not use a runtime exception? You're claiming it's as severe as something like an NPE (which I don't agree with)--so treat it like one. Personally I'd just check, log the error, and exist w/ an error code. – Dave Newton Aug 05 '18 at 00:09
  • 1
    "my program needs to be run within 28 days of a specified date" You shouldn't use exceptions for something the user does. A user can run your program any time they want, so checking the dates and informing the user of a problem should be a part of your program's normal procedures. – Radiodef Aug 05 '18 at 00:12
  • @Radiodef I understand. I lack knowledge of when Exceptions should really be used. Incorporating this into the program's normal procedures makes more sense. – Robert Engle Aug 05 '18 at 00:16
  • 1
    I'd be tempted to just go with `IllegalArgumentException` with a custom message (hence runtime) or at least take that as a convention to go with a `RuntimeException` for this. Additionally: `TimeUnit.MILLISECONDS.toDays(...);`. – BeUndead Aug 05 '18 at 00:21

2 Answers2

2

If this is something that shouldn't happen and you want to catch it just in case, then it should be RuntimeException. Otherwise, checked (expected) exception.

Shl
  • 3,130
  • 1
  • 17
  • 16
  • This is something that _really_ shouldn't happen, as the program is designed to work with the restriction met, but can easily happen(IE if I try to get data for an event 1.5 months from now, which would be greater than 28 days). Would I then use an Unchecked exception? – Robert Engle Aug 04 '18 at 23:52
  • In that case - checked exception would be a better choice. – Shl Aug 04 '18 at 23:59
  • 1
    If it's user input that can cause the error then just validate your data and write it like a normal program. – Dave Newton Aug 05 '18 at 00:10
1

You shouldn't use Exception at all in this example.

  1. You are using Exception for flow control and you catch it immediately and handle it in the same method. Thus is a bad practice.

Using if statement can easily achieve the flow control in your example.

  1. Your quote is out of context. Gili has explained what he meant by predicable and unpreventable, it doesn't apply to your case.

    : The caller did everything within their power to validate the input parameters, but some condition outside their control has caused the operation to fail.

Update

Since OP has changed the code, it seems more arguable between checked and runtime exception.

But remembering one rule in Effective Java that when you decide between checked and runtime exception, always asked yourself one question: what do you expect the caller to do? Can he do better than just ignore or log the exception and exit?

You new code looks exactly like this, so if you cannot change your code to use if statement, you should use Runtime Exception, instead of Checked.

Jacob
  • 1,776
  • 14
  • 11
  • What should I use then? I specifically want the program to not be able to run if this restriction isn't met, so should I just use the if statement and only System.exit(1)? – Robert Engle Aug 05 '18 at 00:09
  • @RobertEngle it's a little bit log to put in comments. I have answered this in the updated answer. – Jacob Aug 05 '18 at 02:12