3

I am not able to see the message (in React.js catch block) set while throwing Exception (by server in Java).

Situation: User wants to perform some action (via myService), some verification w.r.t action can be done only on back-end, if that fails how to show the user what was the reason of failure?

Service (Java):

@GetMapping(path = {/*Servive_path*/}, produces = APPLICATION_JSON_VALUE)
public MyClass myService(@RequestParam String param) {
    throw new RuntimeException("This is error message");
}

Action (React.js):

const myServive = (param) => {
  return async (dispatch, getState) => {
    return request({
      url: ENDPOINTS.MY_SERVICE,
      method: methods.GET,
      params: { param }
    })
      .then(res => {
        dispatch(saveResult(res));
        dispatch(
          notify({
            title: "Successful",
            message: "It was successfully.",
            status: 200,
            dismissAfter: CONFIG.NOTIFICATION_TIMEOUT
          })
        );
      })
      .catch(err => {
        console.log("err.data: ", err.data); //Output-> err.data: 
        console.log("err.message: ", err.message); //Output-> err.message: undefined
        dispatch(
          notify({
            title: "Some error occured",
            message: **//Want to set the error message**,
            status: "error",
            dismissAfter: CONFIG.NOTIFICATION_TIMEOUT
          })
        );
      });
  };
};

Want to show the exception message by setting value in massage in catch block of action.

Output

err.data: ""
err.message: undefined

Also,

err.status: 500
err.request.response: ""
err.request.responseText: ""
err.request.responseType: ""
err.request.status: 500
err.request.statusText: ""

Please help.

Prem
  • 316
  • 1
  • 5
  • 23
  • Is this maybe the same problem? https://stackoverflow.com/questions/43800998/why-do-fetch-errors-not-have-a-stacktrace-in-my-single-page-application – Janos Vinceller May 10 '20 at 22:44

3 Answers3

3

By default in case of exception Spring return http status 500 with Content-Type: text/html;charset=UTF-8 and generates html page with error description. Your error description will be in the last line of this page after

<div>There was an unexpected error (type=Internal Server Error, status=500).</div>

and will look like

<div>This is error message</div>

Of course you can write crutch in your code and parse this page using React, but I wouldn't recommend so. It's much better to add Controller advice and write custom exception handling. In your case something like this

import lombok.Value;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
public class ErrorHandler {

    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ExceptionRestResponse handleCustomException(Exception exception) {
        return new ExceptionRestResponse(500, exception.getMessage());
    }

    @Value
    public static class ExceptionRestResponse {
        int code;
        String message;
    }
} 

Then you will get response with Content-Type: application/json which will look like

{
    "code": 500,
    "message": "This is error message"
} 
Bohdan Petrenko
  • 997
  • 2
  • 17
  • 34
  • Hi, Thanks for the response. Added ```constructor``` in ```ExceptionRestResponse``` as required. CE at ```@Value```, 'The annotation @Value is disallowed for this location'. – Prem May 05 '20 at 05:40
  • I used `@Value` for conciseness. You can replace it with constructor and getters. Or you have to install lombok plugin to your IDE. I tested code sample which I posted on my machine, so all should work. – Bohdan Petrenko May 05 '20 at 07:45
  • Removed the @Value. Debugged the code and I can see method ```handleCustomException``` is being executed but can't see message in UI. Can you please tell me what would be the complete path of property ```message``` in object ```err```? – Prem May 05 '20 at 10:07
  • getter/setter for ```code```,```message``` required in order to resolve above problem. – Prem May 05 '20 at 15:49
  • Make sure the @Value annotation is from lombok and not Spring. You can also take a look at - https://mkyong.com/spring-boot/spring-rest-error-handling-example/ or https://www.baeldung.com/spring-mvc-controller-custom-http-status-code with working examples – indranil32 May 09 '20 at 17:36
  • Hi @Bohdan Petrenko, Even after handling exception in advice the stack trace is being logged in server console. I want to prevent the stack trace print once advice has handled that exception. How to do the same.? – Prem Jun 01 '20 at 06:44
1

Step 1 : Define your exception with the right status code

Example

ResponseStatus(code = HttpStatus.NOT_FOUND)
public class UserNotFoundException extends RuntimeException {
    public UserNotFoundException(String id) {
        super(String.format("User with id %s does not exist.", id));
    }
}

Enable the details in the application.properties

server.error.include-message=always

Sample result

{
    "timestamp": "2022-10-21T04:54:43.916+00:00",
    "status": 404,
    "error": "Not Found",
    "message": "User with id test@test.com does not exist.",
    "path": "/api/authentication/password-recovery"
}
jfk
  • 4,335
  • 34
  • 27
0

You can use the ResponseStatusException to send error message to reactjs.

@RequestMapping(method = RequestMethod.GET, value = "/get")
public List<MyInfo> getInfo(){
   try {
          // code to return
       } catch (InvalidObjectException | InvalidOperationException | OperationNotPermittedException | UserPermissionNotAvailableException e) {
    // throwing custom exceptions
    throw new ResponseStatusException(HttpStatus.FORBIDDEN, e.getMessage(), e);
        } 
   catch (Exception e) {
        throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, e.getMessage(), e);
       }
   }

Instead of e.getMessage(), you may use a specific error message.

Run console.error(error) to see the structure of the error response and display it accordingly. The error response may look like this:

"error" : {
     "status": 403,
     "statusText": "FORBIDDEN",
     "message": "User does not have permission to perform this operation",
     "timestamp": "2020-05-08T04:28:32.917+0000"
     ....
}

More here: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/server/ResponseStatusException.html

Nikhil
  • 1,126
  • 12
  • 26
  • Thanks for reply. Could not find any type with name ```ResponseStatusException```. Can you please specify the package? – Prem May 10 '20 at 18:00
  • Please see the link at the bottom that I've included in the answer. It's part of the Spring Framework since 5.0. – Nikhil May 10 '20 at 18:04
  • ```ResponseStatusException``` is since 5.0 but we are using 4.3.x. Otherwise would have been a good choice. – Prem May 10 '20 at 18:06
  • You can look through other solutions here including older Spring versions: https://www.baeldung.com/exception-handling-for-rest-with-spring – Nikhil May 10 '20 at 18:15