Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SonarQube error: Refactor this method to throw at most one checked exception

I am using SonarQube and it shows the following error:

Public methods should throw at most one checked exception.

// Noncompliant
public void delete() throws IOException, SQLException { /* ... */ }

// Compliant
public void delete() throws SomeApplicationLevelException { /* ... */ }

Does this means, SomeApplicationLevelException is a parent class and IOException and SQALException are derived from it? And we should throw the parent class exception? Thereby adhering to method throwing only 1 checked exception?

Because I have 2 exceptions that i have defined say for example Exception1 and Exception2 that extend Exception. And my method say, sampleMethod() throws them i.e,

public void sampleMethod() throws Exception1, Exception2 {
}

And the error is shown here. So should I have one class as parent (say MainException) and derive Exception1 and Exception2 from it and throw parent exception class? Like below:

public void sampleMethod() throws MainException {
}

Is the above solution proper?

like image 633
pgman Avatar asked Mar 09 '23 01:03

pgman


2 Answers

If you have a method in your application that is declared as throws SQLException, IOException, you are probably leaking internal implementation details to your method's users. Specifically, you're saying:

  1. Your method is implemented using JDBC and file I/O. Your users don't care how your method is implemented; they only care about what your method does.

  2. Your method, including any future version of it, will never throw any other checked exception. If in future you change your method so that it might throw another checked exception, it will break backwards compatibility.

The advice is to create your own application-specific class (derived from Exception), and only throw that in your method. You can, if you like, wrap the SQLException or the IOException (or any other exception) inside your application-specific exception as the cause.

Note, however, that there is a school of thought that says Java checked exceptions are a bad idea (and one of the reasons C#, and more modern languages such as Kotlin, don't have checked exceptions).

UPDATE: the above answer related to the first version of the question (edit #1). The question was subsequently updated to point out that the two thrown exceptions were application-defined ones, so therefore much of the above rationale no longer applies. The answer to the updated question is explained in this post.

like image 127
Klitos Kyriacou Avatar answered Apr 06 '23 00:04

Klitos Kyriacou


IOexception and sqlexception both are checked exception s,totally different from each other , now if we extend both from one exception and throw the parent exception , which is not a mandatory in java, it will be kind of misguiding the user of the api.

However, if you want to do it in ur app to avoid sonarqube error , you can catch all your specific exceptions and throw a custom exception wrapping the original exception information in exception message.

for example

try{

      ///piece of code that throws IOException and SQLException
}catch(IOException | SQLException ex){
   throw new DataException(ex,"Any customized message you want");
}

This DataException will then will be included in the throws clause of method signature having this try catch.

DataException extends Exception class and by passing ex in the contructor you are wrapping the original exception in custom exception with your original exception info preserved.

like image 25
pndey Avatar answered Apr 05 '23 22:04

pndey