Is there a way for ExceptionHandlers to output an argument when an unchecked exception is thrown?

68 views Asked by At
@Component
public class Fetcher {
    private void sendGet(String url) {
        someMethodThatCanThrowUncheckedException();
    }
}

@Controller
public class TestController {
    @Autowired
    private Fetcher fetcher;

    @RequestMapping(value = {"/content"}, method = RequestMethod.GET)
    @ResponseBody
    public String getContent(@RequestParam(value = "url", required = true) String url) {
        fetcher.sendGet(url);
        return "Success";
    }

    @ExceptionHandler({Exception.class})
    @ResponseBody
    public String handleUncaughtException(final Exception exception) {
        return "An internal error has occured trying to fetch url: " + url;
    }
}

I would like a way to be able to output the variable url in handleUncaughtException. However, since the exception comes from another class Fetcher, is there any way I can know what the url parameter was that likely caused this unchecked exception?

Correct me if I'm wrong, but I believe I can't just store the url as a field in TestController, because I'm calling the /content endpoint concurrently.

1

There are 1 answers

2
Sotirios Delimanolis On

What you can do is set the url in the request attributes and retrieve it in your @ExceptionHandler.

@RequestMapping(value = {"/content"}, method = RequestMethod.GET)
@ResponseBody
public String getContent(@RequestParam(value = "url", required = true) String url, HttpServletRequest request) {
    request.setAttribute("url", url);
    fetcher.sendGet(url);
    return "Success";
}

And retrieve it

@ExceptionHandler({Exception.class})
@ResponseBody
public String handleUncaughtException(final Exception exception, HttpServletRequest request) {
    String url = (String) request.getAttribute("url");
    if (url != null) 
        return "An internal error has occured trying to fetch url: " + url;
    else 
        return "something else";
}

You should probably make the attribute key something constant.