Как показать сообщение об исключении сервера (Java) в React. js - PullRequest
4 голосов
/ 29 апреля 2020

Мне не удается увидеть сообщение (в React. js catch block), установленное при создании исключения (по серверу в Java).

Ситуация: Пользователь хочет чтобы выполнить какое-либо действие (через myService), какое-либо действие по проверке может быть выполнено только на бэкэнде, если не удается показать пользователю, в чем причина сбоя?

Служба (Java):

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

Действие (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
          })
        );
      });
  };
};

Хотите показать сообщение об исключении, установив значение в массаже в блоке действия catch.

Вывод

err.data: ""
err.message: undefined

Также

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

Пожалуйста, помогите.

Ответы [ 3 ]

2 голосов
/ 04 мая 2020

По умолчанию в случае исключения Spring возвращает статус http 500 с Content-Type: text / html; charset = UTF-8 и генерирует страницу html с описанием ошибки. Ваше описание ошибки будет в последней строке этой страницы после

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

и будет выглядеть как

<div>This is error message</div>

Конечно, вы можете написать костыль в вашем коде и проанализировать эту страницу, используя React , но я бы не рекомендовал так. Гораздо лучше добавить Совет контроллера и написать собственную обработку исключений. В вашем случае что-то вроде этого

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;
    }
} 

Тогда вы получите ответ с Content-Type: application / json, который будет выглядеть как

{
    "code": 500,
    "message": "This is error message"
} 
0 голосов
/ 09 мая 2020
  1. Укажите адрес конечной точки, который обрабатывает всех типов ошибок и исключений , в web.xml:

    <error-page>
        <location>/error</location>
    </error-page>
    
  2. Добавить соответствующий метод обработчика ошибок:

    @RequestMapping(value = "/error", produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<?> handleError(
            @RequestAttribute(name = "javax.servlet.error.status_code",
                    required = false) Integer errorCode,
            @RequestAttribute(name = "javax.servlet.error.exception",
                    required = false) Throwable exception) {
    
        if (errorCode == null) {
            errorCode = 500;
        }
    
        String reasonPhrase;
        if (exception != null) {
            Throwable cause = exception.getCause();
            if (cause != null) {
                reasonPhrase = cause.getMessage();
            } else {
                reasonPhrase = exception.getMessage();
            }
        } else {
            reasonPhrase = HttpStatus.valueOf(errorCode).getReasonPhrase();
        }
    
        HashMap<String, String> serverResponse = new HashMap<>();
        serverResponse.put("errorCode", String.valueOf(errorCode));
        serverResponse.put("reasonPhrase", reasonPhrase);
    
        return ResponseEntity.status(errorCode).body(serverResponse);
    }
    
  3. На внешнем интерфейсе (я написал это в AngularJS, но должно быть нечто подобное в React):

    http({
        url: '/someEndpoint',
        method: "POST",
        headers: {'Content-Type': undefined },
    }).then((response) => successCallback(response),
        (response) => errorCallback(response));
    
    let successCallback = function(response) {
        // console.log(response);
        mdToast.show({
            position: 'bottom right',
            template: scope.templates.success('Success message'),
        });
    };
    
    let errorCallback = function(response) {
        // console.log(response);
        mdToast.show({
            position: 'bottom right',
            template: scope.templates.error('Error message'),
        });
        if (response && response.data && response.data.reasonPhrase) {
            mdToast.show({
                position: 'bottom right',
                template: scope.templates.error(response.data.reasonPhrase),
            });
        }
    };
    

    Сначала он сообщает, что произошла ошибка, а затем говорит, что это была ошибка.


Например, если сервер возвращает что-то неожиданное:

@GetMapping({"/", "/index.html"})
public ResponseEntity<?> getMainPage() throws Exception {
    throw new Exception("Something unexpected..");
}

Клиент получает такое сообщение JSON:

{
    "reasonPhrase": "Something unexpected..",
    "errorCode": "500"
}

Или сервер может вернуть что-то менее неожиданное:

@GetMapping({"/", "/index.html"})
public ResponseEntity<?> getMainPage() {
    try {
        // expected actions
        // . . .
    } catch (Exception e) {
        HashMap<String, String> serverResponse = new HashMap<>();
        serverResponse.put("errorCode", "500"));
        serverResponse.put("reasonPhrase", "Internal Server Error");

        return ResponseEntity.status(500).body(serverResponse);
    }
}

Клиент:

{
    "reasonPhrase": "Internal Server Error",
    "errorCode": "500"
}

Кроме того, если клиент запрашивает недоступный ресурс или несуществующую страницу, он получает:

{
    "reasonPhrase": "Not Found",
    "errorCode": "404"
}
0 голосов
/ 08 мая 2020

Вы можете использовать ResponseStatusException для отправки сообщения об ошибке на 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);
       }
   }

Вместо e.getMessage() вы можете использовать указанное c сообщение об ошибке.

Запустите console.error(error), чтобы увидеть структуру ответа об ошибке и отобразить ее соответствующим образом. Ответ об ошибке может выглядеть следующим образом:

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

Подробнее здесь: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/server/ResponseStatusException.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...