java:S1989 Exceptions should not be thrown from servlet methods

We are trying to solve violations raised by rule
java:S1989 Exceptions should not be thrown from servlet methods

To guarantee correct and consistent handling of the exceptions, this should be implemented in the base class AbstractHttpServlet which must then be used within our code base for servlets.

However it seems that Sonar is not able to recognize that the exceptions are correctly handled in the base class:

public abstract class AbstractHttpServlet extends HttpServlet {

    /**
     * This method is final to guarantee consistent logging and error handling. Derived classes should override
     * {@link doGetSafely}.
     */
    @Override
    protected final void doGet(HttpServletRequest req, HttpServletResponse resp) {
        doSafely(() -> doGetSafely(req, resp)); // NOSONAR java:S1989
    }

    /**
     * Replacement for {@link HttpServlet.doGet} which can be overridden in derived classes. The use of the class
     * {@link AbstractHttpServlet} instead of {@link HttpServlet} guarantees consistent logging and error handling.
     *
     * @throws Exception
     *             may be thrown in case of an error
     */
    protected void doGetSafely(HttpServletRequest req, HttpServletResponse resp) throws Exception { // NOSONAR
        super.doGet(req, resp); // NOSONAR java:S1989
    }

    /** Handle a servlet request. If an error occurs, it is sanitized. */
    protected void doSafely(ThrowingRunnable runnable) {
        try {
            runnable.run();
        } catch (Throwable t) {
            LOGGER.warn("Error in servlet");
        }
    }

    /** Internal interface for a {@link Runnable} which can also throw checked exceptions */
    protected interface ThrowingRunnable {
        /** Execute code */
        public void run() throws Throwable; // NOSONAR
    }

We then use the base class in a concrete servlet implementation.
However Sonar still complains the exception is not handled correctly if the method handleGetRequest is called.

public class MyServlet extends AbstractHttpServlet {

    @Override
    public void doGetSafely(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        if (isSystemReady()) {
            handleGetRequest(req, resp);	// Handle the following exception that could be thrown by "doGetRequest": IOException.
        }
    }
	
    protected void handleGetRequest(HttpServletRequest request, HttpServletResponse response) throws IOException {
	}
}

It it our goal that classes like MyServlet inheriting from AbstractHttpServlet are recognized as correct by the Sonar rule java:S1989 as this is properly handled in AbstractHttpServlet.
How do we have to modify our solution to make Sonar accept it?
Thanks

We are using SonarQube Enterprise Edition Version 9.9.1 (build 69595)

No idea why, but now it seems to work - without changes in the code or on Sonar…
Thanks, Thomas

Now the issues are back, I still have no clue what caused it.
Anyhow I would be glad now, if we could get some assistance.
Thanks, Thomas

Hi @Thomas_Mauch,

Thanks for reporting!

This is an FP and it is interesting we encounter it just now, years after implementation. Here is the ticket for it: SONARJAVA-4603.

Cheers,
Erwan

1 Like