Proposal: Infer checked exceptions from private methods

negora public at negora.com
Thu Mar 3 13:08:19 UTC 2022


Hi:

I've seen many programmers propagate all checked exceptions up the call 
stack,
from multiple private methods to the first non-private method of the class.
There, some exceptions are allowed to propagate, whereas others are wrapped
with one or more unchecked exceptions.

So I would like to propose a variation of the `throws` clause, such as 
`throws
uncaught` or `throws *`, so that the compiler infers which checked 
exceptions
are thrown. **This feature would be limited to private methods,** so that
developers are forced to think about their public APIs and don't let
implementation details leak.

Thanks to this, propagating exceptions inside a class would be super 
easy and
would not clutter the code so much. I work in big server applications 
and some
times the list of exceptions to "carry" between private methods is so long,
that even the simplest method takes multiple lines of code, making it 
hard to
read.

In addition to this, if you changed the implementation in the future, 
you would
have not to worry much about the exceptions thrown by the private methods,
because you could make the necessary changes only in the non-private 
methods.

Example with irrelevant parts omitted:

```
/* This method does nothing special. */
public void addStudentToRepository (
     String name,
     String surname
     Integer schoolID)
     throws SchoolNotFoundException {

   try {

     ...
     School school = findSchool (schoolID);
     ...

   } catch (UnavailableRepositoryException | WrongIDTypeException ex) {
     throw new ImplementationException (ex);
   }

}

/* Here is the interesting part. */
private School findSchool (Integer id)
     throws uncaught {
         /* ^^^ This is equivalent to throw
          * "UnavailableRepositoryException",
          * "WrongIDTypeException",
          * and "SchoolNotFoundException" separately.
          */

   School school = repository.findObject (id, School.class);
                           /* ^^^ This throws
                            * "UnavailableRepositoryException"
                            * and  "WrongIDTypeException".
                            */
   if (school != null) {
     return school;
   } else {
     throw new SchoolNotFoundException (id);
   }

}
```

This example is very basic. I know that `UnavailableRepositoryException` and
`WrongIDTypeException` could inherit from a common 
`RepositoryException`, but:

1. You lose the specific types of the exceptions.

1. Sometimes that's not an option, because the exceptions come from 
different
libraries or frameworks.

Thank you!

Best regards,
negora.


More information about the amber-dev mailing list