Какой лучший способ справиться с ошибкой на стороне сервера и на стороне клиента с помощью nodejs + express - PullRequest
2 голосов
/ 26 июня 2019

Хотелось бы узнать лучший способ устранения ошибок в ответе - запрос. У меня есть этот маршрут, который получает запрос:

app.get('/getInfo', function (req, res, next) {
    let obj = {}
    try {
        obj = { 
            ...                
            date: lastUpdatedDate('./utils/appVersion.js'),
            ...
        }
        res.status(200).send(obj)
    } catch (error) {
        console.log(error.message)
        res.send({error: "The data wasn't load"})
    }       
})

И эта функция, где сделан запрос

getInfo () {
    axios.get(process.env.REACT_APP_HOST + '/getInfo')
      .then(resp => {
        this.appInfoHandler(resp.data)
      })
      .catch(function (error) {    
        console.log(error)
      })
  }

Как лучше всего справиться с ошибкой, если она возникает на стороне сервера? Предположим, что в этом блоке кода каталог не существует: lastUpdatedDate('./directoreyDoesntExists/appVersion.js'),

Итак, мой код переходит в блок catch.

Должен ли я отправить сообщение об ошибке следующим образом:

res.send({error: "The data wasn't load"})

Должен ли я установить такой статус?

  res.status(500).send({error: "The data wasn't load"})

Или я должен установить статус с другим кодом статуса?

Исходя из этого, как лучше всего справиться с этим в моем методе внешнего интерфейса getInfo(), чтобы получить сообщение об ошибке и отобразить сообщение об ошибке в веб-интерфейсе?

Должен ли я сделать if else внутри блока .then, как это?

 getInfo () {
      axios.get(process.env.REACT_APP_HOST + '/getInfo')
      .then(resp => {
            if(resp.status === 200){
                 this.appInfoHandler(resp.data)
            }else if (resp.status === 400){
                  //print error message on web interface
            }else if (resp.status === 500){
                  //print error message on web interface
          })
          .catch(function (error) {    
            console.log(error)
          })

Или я должен разобраться с этой ошибкой прямо в блоке catch, как это

getInfo () {
    axios.get(process.env.REACT_APP_HOST + '/getInfo')
      .then(resp => {
        this.appInfoHandler(resp.data)
      })
      .catch(function (error) {    
        //print error message on web interface
      })
  }

Ответы [ 4 ]

4 голосов
/ 26 июня 2019

Для этого случая

res.send({error: "The data wasn't load"}) 

против

res.status(500).send({error: "The data wasn't load"})

отправить статус просто более подробно, но оба в порядке. check Правильный способ установки статуса ответа и содержимого JSON

Для этого случая зависит, что вам нужно

then(resp => {
            if(resp.status === 200){
                 this.appInfoHandler(resp.data)
            }else if (resp.status === 400){
                  //print error message on web interface
            }else if (resp.status === 500){
                  //print error message on web interface
          })
          .catch(function (error) {    
            console.log(error)
          })

против

getInfo () {
    axios.get(process.env.REACT_APP_HOST + '/getInfo')
      .then(resp => {
        this.appInfoHandler(resp.data)
      })
      .catch(function (error) {    
        //print error message on web interface
      })
  }

Вы можете обработать все ошибки, отправив их в блок catch

else if (resp.status === 400){
                  //print error message on web interface

здесь не печатается ошибка, а выдается новая ошибка, которая отправит ее в блок catch

throw new ApiError("UserNotFount",400,"not found");
throw new Error('Error 400, not found');
3 голосов
/ 26 июня 2019

Для этого случая

res.send({error: "The data wasn't load"}) 

против

res.status(500).send({error: "The data wasn't load"})

Я бы предложил отправить ошибку, а также код состояния, потому что это будет более наглядным для клиента.

и для второго случая

getInfo () {
      axios.get(process.env.REACT_APP_HOST + '/getInfo')
      .then(resp => {
            if(resp.status === 200){
                 this.appInfoHandler(resp.data)
            }else if (resp.status === 400){
                  //print error message on web interface
            }else if (resp.status === 500){
                  //print error message on web interface
          })
          .catch(function (error) {    
            console.log(error)
          })

против

getInfo () {
    axios.get(process.env.REACT_APP_HOST + '/getInfo')
      .then(resp => {
        this.appInfoHandler(resp.data)
      })
      .catch(function (error) {    
        //print error message on web interface
      })
  }

В этом случае я бы предложил использовать блок catch непосредственно всякий раз, когда вы получаете сообщение об ошибке, поскольку состояние ответа зависит от ошибки, а не наоборот

2 голосов
/ 26 июня 2019

Как новичок, работающий над REST Api, вы должны взглянуть на рекомендации - Microsoft вполне законны: https://docs.microsoft.com/en-us/azure/architecture/best-practices/api-design.

По сути, вам нужно возвращать правильный HTTP-код для каждого запроса, принятьвзгляните на https://http.cat/ - например, если запрос искажен, верните 400, а если пользователь не авторизован, верните 401:

if (!req.body.name) {
  res.status(400).send({ error: 'missing user name' }); // 400 bad request
}
const user = getUser(req.body.name, req.body.pass);

if(!user) {
  res.status(401).send({ error: 'user does not exist' }); // 401 unauthorized
}

try {
  const token = createToken(user);
  // better to set a cookie
  res.status(200).send({ token }); // 200 success
} catch(e) {
  res.status(500).send({ erroe: e.message }); // 500 internal error
}

if(isTeapot) {
  res.status(418).send({ error: 'I can only make tea' }); // 418 teapot, totally real
}

Чтобы упростить задачу, существует множество библиотек дляпомочь вам генерировать лучшие сообщения об ошибках и лучше обрабатывать ошибки, один из моих любимых - праздновать

2 голосов
/ 26 июня 2019

Любой код состояния, отличный от 200, будет означать неудачный, поэтому вам не нужно использовать эти операторы if-else.Лучшая альтернатива - перехватить ошибку и отправить ее с ответом как есть.Преимущество состоит в том, что вы получите тип ошибки, произошедшей без жесткого кодирования кодов состояния.(например, мы принимаем код состояния здесь как 400 неудачных)

 .catch(function (error) {    
        //print error message on web interface
        res.status(400).send(JSON.stringify(error, undefined, 2));
      });

Используя метод stringify, вы также можете распечатать точную ошибку на консоли.

.catch(function (error) {    
            console.log(JSON.stringify(error, undefined, 2));
          });

параметры в методе stringify:

  1. объект ошибки

  2. undefined: массив, содержащий ключи для фильтрации ключей в объекте (здесь ошибка).Все эти ключи, присутствующие в этом массиве, являются только теми, которые не отфильтрованы.

  3. 2: используется для ввода пробела в представление объекта

...