Search code examples
javaspring-bootsonarlint

SonarLint: Return an empty collection instead of null


I'm making an ajax call to a method that returns a list of object, if something happens while getting the data in a try-catch block I have a response.setStatus(400) to then show the error in the front-end, also there I'm returning null, there is where I'm getting the SonarLint notification. Now if I change that to an empty collection then I get below error:

getWriter() has already been called for this response

I think the above is because I'm returning the empty collection and the http response status 400. If I leave it null then all works fine, just that SonarLint notification.

@GetMapping("/runquery")
@ResponseBody
public List<Map<String, Object>> runQuery(@RequestParam(name = "queryId") String queryId, @RequestParam(name = "formData") String formData, HttpServletResponse response) throws IOException {
    (...)

    try {
        queryResult = namedParameterJdbcTemplateHive.queryForList(query, paramSource);

        for (Map<String, Object> map : queryResult) {
            Map<String, Object> newMap = new HashMap<>();
            for (Map.Entry<String, Object> entry : map.entrySet()) {                    
                String key = entry.getKey();
                Object value = entry.getValue();

                if (key.contains(".")) {
                    key = key.replace(".", "_");
                    newMap.put(key, value);
                } else {
                    newMap.put(key, value);
                }
            }
            queryResultFinal.add(newMap);
        }


    } catch (Exception e) {
        response.setStatus(400);
        response.getWriter().write(e.getMessage());
        return null;  <-- SonarLint notification
    }

    return queryResultFinal;        
}

Any idea on how to fix this notification?


Solution

  • I would recommend not catching the exception in this method, but instead throw it, and use an exception handler method in your controller to handle it. In that case you will never return null from the method, and Sonar will have nothing to complain about. It will also mean that you are using Spring the way it is designed to be used.

    For example, something like the following:

    @ExceptionHandler
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public void handleException(Exception e) {
        log.error("Exception during request", e);
    }
    

    or the direct equivalent of your current handling:

    @ExceptionHandler
    public ResponseEntity<?> handleException(Exception e) {
        return ResponseEntity.badRequest().body(e.getMessage()).build();
    }
    

    You can remove the HttpServletResponse response parameter from your normal method after switching to an exception handler.