Skip to content
This repository has been archived by the owner on Mar 5, 2023. It is now read-only.

model: convert checked exceptions to runtime exceptions #896

Merged
merged 11 commits into from
Aug 9, 2018

Commits on Aug 9, 2018

  1. Remove redundant throws clauses

    These redundant throws clauses were identified using IntelliJ's
    Analyze->Inspect Code feature, and analyzing the whole project.
    pyokagan committed Aug 9, 2018
    Configuration menu
    Copy the full SHA
    000dbd1 View commit details
    Browse the repository at this point in the history
  2. model: expose hasPerson(Person) functionality

    In the next few commits, we are going to be converting
    DuplicatePersonException and PersonNotFoundException into runtime
    exceptions.
    
    To do that, we need to be able to query the model to determine if a
    person exists in the address book.
    
    This functionality is already available in
    `UniquePersonList#contains(Person)`, but was simply not exposed. Let's
    expose it.
    pyokagan committed Aug 9, 2018
    Configuration menu
    Copy the full SHA
    ac42c32 View commit details
    Browse the repository at this point in the history
  3. AddCommand: explicitly perform duplicate person check

    In the next few commits, we will convert DuplicatePersonException into a
    runtime exception.
    
    In preparation for that, let's teach AddCommand to not depend on
    catching DuplicatePersonException for its control flow.
    
    Since DuplicatePersonException is still a checked exception, we need to
    add an ugly `throw new AssertionError("should not happen")`, but this
    will be removed in later commits once we convert
    DuplicatePersonException into a runtime exception.
    pyokagan committed Aug 9, 2018
    Configuration menu
    Copy the full SHA
    5e14e42 View commit details
    Browse the repository at this point in the history
  4. EditCommand: explicitly perform duplicate person check

    In the next few commits, we will convert DuplicatePersonException into a
    runtime exception.
    
    In preparation for that, let's teach EditCommand to not depend on
    catching DuplicatePersonException for its control flow.
    
    Since DuplicatePersonException is still a checked exception, we need to
    add an ugly `throw new AssertionError("should not happen")`, but this
    will be removed in later commits once we convert
    DuplicatePersonException into a runtime exception.
    pyokagan committed Aug 9, 2018
    Configuration menu
    Copy the full SHA
    e66d31c View commit details
    Browse the repository at this point in the history
  5. model: make DuplicatePersonException a RuntimeException

    DuplicatePersonException is a checked exception. It is thrown by methods
    such as `UniquePersonList#add(Person)`,
    `UniquePersonList#setPerson(Person, Person)` etc. to signify that
    certain preconditions were not met -- namely that the operation would
    cause the "no duplicate persons in address book/UniquePersonList"
    constraint to be violated.
    
    Using checked exceptions for such a purpose is slightly useful in that
    it will force callers to handle the case where the above preconditions
    are not met, such as when the methods are called with invalid user
    input.
    
    However, it imposes a HUGE cost on callers where the preconditions are
    already known to be met (e.g. in test code, or when the user input has
    already been validated before hand). In such a case, callers are forced
    to add try-catch blocks around the method call even if they know that
    the exception will never be thrown, bloating up the code. It is also
    impossible to test the catch blocks as well since correct code will
    ensure that the precondition holds and thus the exception will never be
    thrown, leading to reduced code coverage.
    
    Checked exceptions also don't work very well with the Java Streams API,
    since the API doesn't accept lambdas which could throw checked
    exceptions.
    
    In AB-4, the amount of code which benefits from
    DuplicatePersonException being a checked exception is much smaller than
    the amount of code which is negatively impacted.
    
    As such, let's make the tradeoff in the other direction, by making
    DuplicatePersonException a RuntimeException. New callers _could_ forget
    to check that the preconditions hold before calling the methods in
    question (although test cases should catch that), but this is balanced
    out by the huge benefit of having more concise and testable code.
    pyokagan committed Aug 9, 2018
    Configuration menu
    Copy the full SHA
    6817bd3 View commit details
    Browse the repository at this point in the history
  6. model: make PersonNotFoundException a RuntimeException

    PersonNotFoundException is a checked exception. It is thrown by methods
    such as `UniquePersonList#remove(Person)`,
    `UniquePersonList#setPerson(Person, Person)` etc. to signify that
    certain preconditions were not met -- namely that the person provided to
    those methods does not exist in the address book/UniquePersonList.
    
    Using checked exceptions for such a purpose is slightly useful in that
    it will force callers to handle the case where the above preconditions
    are not met, such as when the methods are called with invalid user
    input.
    
    However, it imposes a HUGE cost on callers where the preconditions are
    already known to be met (e.g. in test code, or when the user input has
    already been validated before hand). In such a case, callers are forced
    to add try-catch blocks around the method call even if they know that
    the exception will never be thrown, bloating up the code. It is also
    impossible to test the catch blocks as well since correct code will
    ensure that the precondition holds and thus the exception will never be
    thrown, leading to reduced code coverage.
    
    Checked exceptions also don't work very well with the Java Streams API,
    since the API doesn't accept lambdas which could throw checked
    exceptions.
    
    In AB-4, the amount of code which benefits from PersonNotFoundException
    being a checked exception is much smaller than the amount of code which
    is negatively impacted.
    
    As such, let's make the tradeoff in the other direction, by making
    PersonNotFoundException a RuntimeException. New callers _could_ forget
    to check that the preconditions hold before calling the methods in
    question (although test cases should catch that), but this is balanced
    out by the huge benefit of having more concise and testable code.
    pyokagan committed Aug 9, 2018
    Configuration menu
    Copy the full SHA
    73693de View commit details
    Browse the repository at this point in the history
  7. AddressBookSystemTest: remove unnecessary catch block

    The code in the `try` block does not throw any checked exceptions.
    pyokagan committed Aug 9, 2018
    Configuration menu
    Copy the full SHA
    1c39319 View commit details
    Browse the repository at this point in the history
  8. commons: remove DuplicateDataException

    It is not used anymore.
    pyokagan committed Aug 9, 2018
    Configuration menu
    Copy the full SHA
    bc1b068 View commit details
    Browse the repository at this point in the history
  9. UniquePersonList: check for null arguments more thoroughly

    Some methods do not explicitly check that their arguments are non-null
    with `requireNonNull(...)`.
    
    Let's fix them to be consistent with the rest of the code base.
    pyokagan committed Aug 9, 2018
    Configuration menu
    Copy the full SHA
    e747390 View commit details
    Browse the repository at this point in the history
  10. UniquePersonListTest: move to seedu.address.model.person package

    Since UniquePersonList is in the `seedu.address.model.person` package,
    its corresponding test UniquePersonListTest should be in the same
    package as well.
    pyokagan committed Aug 9, 2018
    Configuration menu
    Copy the full SHA
    8e370e4 View commit details
    Browse the repository at this point in the history
  11. UniquePersonListTest: add some more tests

    More test coverage is always nice.
    
    In particular, we want to check that UniquePersonList's methods throw
    DuplicatePersonException and PersonNotFoundException where relevant.
    These cases were not tested by existing test code.
    pyokagan committed Aug 9, 2018
    Configuration menu
    Copy the full SHA
    b2875e0 View commit details
    Browse the repository at this point in the history