Axios: O erro de captura do Axios retorna um erro de javascript, não uma resposta do servidor

Criado em 17 jun. 2017  ·  87Comentários  ·  Fonte: axios/axios

Estou tentando detectar erros de validação do servidor.

Código:

axios.post('/formulas/create', {
       name: "",
       parts: ""
})
.then( 
    (response) => { console.log(response) },
    (error) => { console.log(error) }
);

Saída de registro do console

Error: Request failed with status code 422
    at createError (app.js:6765)
    at settle (app.js:29489)
    at XMLHttpRequest.handleLoad (app.js:6600)

Saída da guia de rede
{"nome": ["O campo do nome é obrigatório."], "partes": ["O campo das partes é obrigatório."]}

Devo estar vendo um objeto que contém a validação de formulário JSON, pois essa é a resposta na minha guia de rede, parece que recebo a saída de captura JS?

Também tentei o seguinte:

axios.post('/formulas/create', {
    name: "",
    parts: ""
})
.then(response => { 
    console.log(response)
})
.catch(error => {
    console.log(error)
});

Mesmo resultado

Mais pessoas parecem ter o mesmo problema usando o mesmo ambiente que eu aqui.
https://laracasts.com/discuss/channels/vue/issues-with-axios-catch-method

  • Versão Axios: ^ 0.16.2
  • VueJS 2.3.4
  • Vue-template-compiler 2.3.4
  • Laravel-mix
  • Ambiente: nó v6.4.0, chrome 58, Mac OSX 10.12.4

Comentários muito úteis

Eu tenho exatamente o mesmo ambiente. Experimente isto:

axios.post('/formulas/create', {
    name: "",
    parts: ""
})
.then(response => { 
    console.log(response)
})
.catch(error => {
    console.log(error.response)
});

Modifique de console.log(error) para console.log(error.response) em catch .

Você também pode usar um interceptor global e rejeitar apenas error.response . O problema é quando console.log tenta mostrar o erro, a representação da string é impressa, não a estrutura do objeto, então você não vê a propriedade .response .

Todos 87 comentários

Eu tenho exatamente o mesmo ambiente. Experimente isto:

axios.post('/formulas/create', {
    name: "",
    parts: ""
})
.then(response => { 
    console.log(response)
})
.catch(error => {
    console.log(error.response)
});

Modifique de console.log(error) para console.log(error.response) em catch .

Você também pode usar um interceptor global e rejeitar apenas error.response . O problema é quando console.log tenta mostrar o erro, a representação da string é impressa, não a estrutura do objeto, então você não vê a propriedade .response .

Caso alguém esteja se perguntando como rejeitar apenas a propriedade response , veja como fazer isso:

axios.interceptors.response.use((response) => {
    return response;
}, function (error) {
    // Do something with response error
    if (error.response.status === 401) {
        console.log('unauthorized, logging out ...');
        auth.logout();
        router.replace('/auth/login');
    }
    return Promise.reject(error.response);
});

A parte importante é return Promise.reject(error.response);

Isso produz o mesmo resultado no caso de a solução acima bagunçar a sintaxe do arquivo JS ao recuar ou minimizar :)

.post('ajax/register/otp', this.registerData)
.then(function (response) {
       return otpSent(response)
})
.catch(function (error) {
      console.log(error.response);
 });

@ gopal-g isso é indefinido para mim.

Bem, @ pedro-mass, nesse caso, pode não haver resposta do lado do servidor. no meu cenário, minha resposta foi JSON quando ocorreu um erro, eu poderia obter a resposta usando error.response

@ gopal-g Se estou observando a guia Rede nas ferramentas de desenvolvimento, posso ver a resposta. É um 401, se isso fizer diferença.

Eu tenho o mesmo erro com @ pedro-mass.

aqui está meu código

async function test () {
try {
  let res = await axios.get('/xxxxx/xxxx')

} catch (e) {
  console.log(e.response) // undefined
}
}

usar "error.response" não funciona, para mim. O problema ocorre quando eu desconectei o servidor de banco de dados e meu servidor web retornou o erro 500.

Guia Rede nas ferramentas de desenvolvimento

código de resposta: 500
corpo de resposta:

{
  "error": {
    "statusCode": 500,
    "name": "Error",
    "message": "read ETIMEDOUT",
    "code": "ETIMEDOUT",
    "errno": "ETIMEDOUT",
    "syscall": "read",
    "stack": "Error: read ETIMEDOUT\n    at exports._errnoException (util.js:1050:11)\n    at TCP.onread (net.js:582:26)"
  }
}

erro do console do Chrome:

Uncaught (in promise) Error: Request failed with status code 500
    at createError (createError.js:15)
    at settle (settle.js:18)
    at XMLHttpRequest.handleLoad (xhr.js:77)

versão

"axios": "^ 0.15.3"

Há um problema em catch : se o erro ocorrer antes de a solicitação ser feita, então em catch você não terá a propriedade err.response , porque ... bem .. .não há resposta. Portanto, o catch detectará qualquer erro. O mesmo se aplica em situações como a de @fabiorecife quando não há resposta por causa de uma falha de rede. Não trate err como um erro HTTP porque nem sempre é esse o caso.

@alsofronie, então qual é o método preferido de tratamento (distinguir um do outro), por exemplo, falhas de comprovação como 413?

Estou tendo um problema semelhante - os devtools do Chrome estão mostrando um 401 , a resposta é {"message":"Identity token has expired"} e eu sou catch( (error) => {...}) - mas error.response em branco. Eu estou me perguntando se isso é porque a chamada anterior OPTIONS associada com GET tem um status de 200 . O que fazer nesse caso e onde é o lugar certo para recuperar o código de status 401 ?

@robbiemu Acho que já está documentado: https://github.com/axios/axios#handling -errors

@mrchief obrigado por isso, é bom error.response está presente, mas os campos são undefined , quaisquer chamadas para valores dentro de response object resulta em erro.

@paolavness , sugiro abrir um novo problema em vez de comentar aqui. Poucos assistem a questões fechadas. Ou talvez até pergunte no StackOverflow.

@mrchief Ah isto está fechado, obrigado por apontar isso. vai fazer.

Eu tive o mesmo problema. Por fim, alterei o código de erro de 401 para 403 e tudo funcionou como eu esperava. Estou supondo que a razão para o objeto de erro vazio e o erro de javascript resultante tem a ver com esta declaração que encontrei na documentação para erros 401:

"A resposta [A 401 error] deve incluir um campo de cabeçalho WWW-Authenticate contendo um desafio aplicável ao recurso solicitado."

Portanto, se você for utilizar um erro 401, deverá incluir um campo de cabeçalho www-authenticate. Se você não quiser fazer isso, basta usar um erro 403.

Bom dia pessoal, Tive esse problema, porém, resolvi alterando minha configuração do apache para habilitar cors no meu servidor. Dê uma olhada no link abaixo

https://enable-cors.org/server_apache.html

Você pode depurar todas as respostas apenas com console.log(JSON.stringify(error))

axios.post (url)
.então ((resposta) => {
// algo
})
.catch ((resposta) => {
if (response.status == undefined) {
alerta ('não autorizado')
}
})

Tive exatamente o mesmo problema descrito por @fabiorecife . Eu resolvi, mas não é a solução mais elegante e não entendo por que isso é necessário.

.catch(error=>{
let errorObject=JSON.parse(JSON.stringify(error));
console.log(errorObject);
dispatch(authError(errorObject.response.data.error));
})

Isso produz os resultados esperados na variável errorObject .

@petruscurtu Eu tenho o mesmo problema! Dose não funciona para mim!
image
Eu não sei por que ele exibe 'no Access-control-allow-origin', mas o servidor configurou isso! O cabeçalho da resposta está ok

image

Resolvido. A API de autenticação não estava respondendo ao cabeçalho correto que deve ter o Access-control-allow-origin

@luxueyan Não sei qual pode ser o problema, pois não sei como você lida com CORS no seu servidor. No que diz respeito ao axios, posso ver um objeto de configuração e solicitação na saída do console. Eu acho que você deve verificar essa saída. Pode estar relacionado ao formato da resposta que seu servidor está enviando de volta.

@luxueyan Parece que você configurou Access-control-allow-origin para http://localhost:8081 (assumindo que esteja configurado no servidor com este endereço http://10.31.143.32:8080 ?) Você pode verificar qual é o URL que você está executando este projeto? É http://localhost:8081 ? Se não for, mesmo que o número da porta seja diferente, ele está violando as regras de domínio CORS.

@petruscurtu A saída é 'JSON.parse (JSON.stringify (erro))' no interceptor de resposta. Não tem propriedade de resposta

@chiefie , tenho certeza de que a configuração 'Access-control-allow-origin' está ok, uma vez que outra API ajax pode responder ao conteúdo correto! Apenas a API do código capcha dá errado。 quando expira , é um erro de resposta com status 478 e os axios não podem obter o corpo de resposta!

Atualizar! Era erro de API do servidor, não tinha configurações de cors no cabeçalho. Agora trabalhe bem.

Obrigado @ juliano-barros foi por causa da origem cruzada. Agora, todas as minhas solicitações de Ajax funcionam bem.

Este erro bruto é gerado sempre que o servidor está inacessível / CORS invalidado.
error.response será apenas undefined .

Acabei de criar um IntegrationError que contém dados de mensagem, status e resposta ... mas sempre seguindo a mesma estrutura. Dessa forma, posso desacoplar axios / erro bruto de minhas manipulações.

Pessoal do Axios, isso deve ser um erro de HTTP, eu acho ... incluindo um error.response .
Isso pode ser verificado como acima

Ontem foi o aniversário de um ano desta edição. Será que alguma vez será "consertado" ou é considerado um "não problema" neste momento?

@frostshoxx Portanto, acho que este é um "problema". Embora eu esteja tendo o mesmo problema que todo mundo, agora entendo o que está acontecendo e posso ver que isso não é um bug ou problema, mas apenas a maneira como o mundo funciona.

Para todos que estão confusos (e para comemorar esse problema ao completar um ano), deixe-me explicar o que está acontecendo e como obter a resposta do servidor.

Como você acabou aqui?

Há muitos motivos pelos quais você pode encontrar o deserto .catch() . Às vezes, o Axios encontra um erro no início da solicitação. Isso às vezes acontece com solicitações CORS. Quando o Axios OPTIONS não está disponível, o Axios entra em pânico e o envia para .catch() antes de realmente obter uma resposta do servidor, portanto, a resposta não está disponível nesses casos.

Alguns de vocês podem dizer: "Não, vejo no DevTools, então a resposta voltou!". Isso nem sempre é verdade porque às vezes o Axios inicia uma solicitação HTTP, apresenta um erro, aborta a si mesmo e envia você para .catch() antes que o servidor responda de volta. Alguns milissegundos depois que o Axios executa a função .catch() , seu servidor pode retornar com uma resposta, que aparece no DevTools porque ainda está ouvindo a resposta. No entanto, o Axios já terminou há muito tempo, então response não estava disponível porque não existia no momento em que o Axios iniciou a função .catch() .

Aqueles de vocês que receberem uma mensagem sobre um erro 4XX ou 5XX do servidor, estão com sorte! Normalmente, há uma resposta do servidor disponível para você porque, para obter esse erro, o Axios teve que esperar pela resposta completa do servidor. Nesses casos, o Axios envia você para .catch() com response mas envolve a resposta em seu próprio objeto error que cria instantaneamente.
Portanto, se você estiver obtendo erros 5XX ou 4XX , provavelmente terá a resposta do servidor disponível, mas está enterrada PROFUNDAMENTE!

Experimente error.response.data.data.message . Isso é confirmado para funcionar para solicitações de API do Laravel que retornam erros do servidor.

Usuários não-Laravel - Você precisará ir pelo menos error.response.data para obter a resposta principal do servidor, mas a maioria dos servidores envolve suas respostas em outro objeto data{} exigindo que você vá um camada mais profunda e, finalmente, acesse a propriedade de resposta desejada, como .message partir daí.

Mas eu fiz Console.Log e ele não contém nenhuma resposta!

Sim, eu sei, mas tente produzir error.response.data qualquer maneira, apenas para me agradar.

Por algum motivo, o Axios modifica a saída de console.log(error) no objeto de erro. Não sei por que eles fazem isso, mas se você escrever console.log(JSON.stringify(error)) , verá o objeto inteiro em toda a sua glória.

Este é JSON serializado que fica difícil de ler depois de cerca de 2 camadas de profundidade. Portanto, você deve copiar tudo e colá-lo em um prettifyer JSON para explorar a estrutura do objeto de erro.


Se você estiver recebendo um erro 500 ou um erro do tipo 400 (ou realmente qualquer código de erro fornecido pelo servidor) no Axios, isso significa que a solicitação foi concluída e que a resposta do servidor está disponível para você!

O problema é que ele é muito profundo e, como o Axios modifica a saída de nosso console.log(error) que a maioria das pessoas faz para ver o objeto error{} , a maioria das pessoas não sabe que ele existe. Mas está aí!

@ VSG24 man !! essa é uma resposta que salva vidas: D

fwiw, JSON.stringify(error) bombas em 0.18.0 devido a referências circulares.

Eu configurei um interceptor que me dá uma resposta do servidor em caso de erro

axios.interceptors.response.use(
  response => {
    // do someting on response
    return response
  },
  error => {
    // do someting on errir
    return Promise.reject(error.response.data) // => gives me the server resonse
  }
)
    try {
      const { data } = await htttp.post(login, payload)
      // do someting with data
    } catch (e) {
      console.log(e) // server response data
    }

@alimirayman Parece funcionar bem se não tivermos que ficar de olho em cada pedido. Mas, quando você precisa rastrear todas as solicitações, não é razoável ter um manipulador de erros repetido em todos os locais do meu código. A menos que eu tenha entendido errado (qual pode ser o caso), axios não deveria ter certeza de que o servidor retornou um erro antes de gerar um erro?

@ hhowe29 use circular-json

Achei este tópico como muitos outros e estou usando axios com módulos vue.js e vuex.

Minha ação do módulo vuex detecta o erro axios e executa o commit (ERROR_HAPPENED, erro) para executar a mutação ERROR_HAPPENED do módulo vuex. Mas o erro chega sem sua propriedade de resposta, resultando em erro. Resposta sendo indefinida se eu tentar definir a resposta para um estado de vuex.

Se eu console.log (error.response) na ação, antes de commit (), posso ver a resposta. Portanto, provavelmente está sendo mutilado por vuex.

Faça um commit (ERROR_HAPPENED, error.response.data) ou verifique se é um 401 na ação e execute algum outro commit dependendo do código de status. Porque essa mutilação só acontece com um código 401. Outros erros como 404 ou 500 são transmitidos às minhas mutações.

Não mutilado. A Vuex não destrói isso, nem mesmo por bug.
Alguns tipos de erros, principalmente dentro dos interceptores do Axios, fazem com que isso não seja exposto.

Alguma atualização?

@AllanPinheiroDeLima desculpe pelo atraso na resposta mas acho que ninguém escreve interceptor em cada local do código de alguém. Escrevemos o interceptor uma vez em uma base de código e o usamos como uma classe auxiliar, que é o número 1. Número 2, a consulta inicial foi que eles não obtiveram _resposta de erro do servidor_, em vez disso, eles obtiveram o _erro de javascript_ no try catch block. havia 2 solução um para mudar a forma como o servidor respondia ao erro ou a forma como o frontend detectava o erro. axios interceptor de erro

Sim, eu concordo. Eu encontrei uma solução para este problema fazendo a integração em meu próprio servidor em vez de usar keycloak bruto. Assim consegui interceptar o erro no servidor e mandar um legível para o front end. Acho que é a única maneira de resolver esse tipo de problema por enquanto :)

Estou tendo o mesmo problema ainda. Usando o interceptor Axios console.log('interceptors', JSON.stringify(error)) i get this log interceptors {"config":{"transformRequest":{},"transformResponse":{},"timeout":0,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","maxContentLength":-1,"headers":{"Accept":"application/json, text/plain, */*","Content-Type":"application/json;charset=utf-8"},"method":"post","url":"http://localhost:5000/api/autenticacao/login","data":"{\"siglaInstituicao\":\"NEAS\",\"usuario\":\"emersoncpaz\",\"senha\":\"belle1903\"}"},"request":{}} but chrome devtools Response Eu tenho a resposta correta da api: A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server) Como obter esta resposta de axios?

Qualquer motivo de erros 5xx não são tratados pelo bloco catch (não retorna um objeto de resposta)? O código de status 502 aparece no console do DevTool, mas não é manipulado pelo Axios.

Isso funcionou para mim (com laravel abort helper: abort (500, 'mensagem'))
`` `
.catch (erro => {
console.log (error.response.data.message);
});

`` `

Alguém tem um exemplo de trabalho completo diferente de um fragmento de código dizendo que isso funcionou? O recorte de 1 linha não ajuda muito se você não tem ideia de a quem eles estão se referindo neste tópico, onde colocaram aquele recorte de código, como é o código de trabalho final?

Estou tentando pegar o erro no inerceptor e com base no código de erro, finalize a solicitação lá com redirecionamento se 401 para fazer o login, ou se for 422, deixe a solicitação voltar para o componente de chamada para permitir a atualização dos erros do formulário.

Alguma ideia?

Estou usando Nuxt axios e meu interceptor onResponseError se parece com:

$axios.onResponseError(error => {
    const code = parseInt(error.response && error.response.status)
    console.log(code, 'Axios onResponseError')
    console.log(error.response.status, 'status')
    console.log(error.config, 'config')
    console.log(error.response, 'response')
    // Do something with response error
    if (error.response.status === 401) {
      console.log('unauthorized, logging out ...')
      app.$auth.logout()
      redirect('/login')
    }
    if (code === 400) {
      // redirect('/400')
      console.log(`400 onResponseError`)
    }
    if (code === 408) {
      console.log(`A timeout happened on url onResponseError`)
    }
    if (code === 418) {
      console.log(`A teapot onResponseError`)
    }
    if (code === 428) {
      console.log(`428 onResponseError`)
      // redirect('/login')
    }
    return Promise.reject(error)
  })

E um exemplo de chamada seria:

async postRecord (clear = false) {
      try {
        const { r } = await this.$axios.$post(this.endPoint, this.formData)
        console.log(r, 'response')
        // do something with response
      } catch (e) {
        console.log(e, 'error in crud') // server response data
        // i should never get here if error since the interceptor should kill the request if 401
       // for testing this request is returning a 401
      } finally {
        this.submitted = false
      }
    },

Obrigado,
Dave

Quando não há internet, o error.response é indefinido - este é o melhor caminho?

Recebo erro em texto simples, tive que usar o seguinte para converter o erro em um objeto.

var errorObj = JSON.parse(JSON.stringify(error));

Isso é para o servidor e não axios, você já tentou cavar no
error.response.status, se for indefinido, você sabe que é uma Internet
problema de conexão ou erro de sintaxe em seu JS

Na quarta-feira, 2 de janeiro de 2019, 15:40 Ibrahim Azhar Armar < [email protected]
escreveu:

Recebo erro em texto simples, tive que usar o seguinte para converter o erro em
um objeto.

var errorObj = JSON.parse (JSON.stringify (erro));

-
Você está recebendo isto porque comentou.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/axios/axios/issues/960#issuecomment-450896476 ou mudo
o segmento
https://github.com/notifications/unsubscribe-auth/AEETt2r3bt2QCixDlzh4fZvWp_1rPkxuks5u_NMEgaJpZM4N9Ljl
.

@kgrosvenor Estou colocando o script do servidor em hibernação e aguardando que o axios ative o tempo limite. Eu acredito que o servidor neste ponto não está respondendo, portanto, disparando o callback no axios.

Estou recebendo a mensagem de erro correta, no entanto o console a mostra em texto simples, portanto, parece apenas o problema de formatação, que não parece relacionado ao servidor.

Se for, estou tentando entender o que no servidor pode estar causando isso?

Você provavelmente está atingindo um tempo limite, então, tente verificar se existe 'resposta' no erro

axios.get()
.then(function(done) {
   //fine and can get done.data
})
.catch(function(err) {
  //catch the error, check it has a response object with lodash 
  if(_.has(err, 'response') {
     console.log(error.response.status);  
     console.log(error.response.data);
 } 
 else {
    console.log("Most likely a server timeout or an internet connection error");
    console.log("error response property is undefined")
 }
}); 

O programador Java me envia uma mensagem de erro com o erro 500 e não consigo lidar com essa mensagem. Então, estou pedindo a ele para retornar o status 200 com mensagem de erro em resposta, mas ele está com raiva de mim e diz que seu cliente HTTP vê todas as mensagens com status 500. Ele acha que sou idiota porque não consigo encontrar mensagem de erro com status 500. Como posso explicar a ele que axios não lida com mensagens de erro 500?

O programador Java me envia uma mensagem de erro com o erro 500 e não consigo lidar com essa mensagem. Então, estou pedindo a ele para retornar o status 200 com mensagem de erro em resposta, mas ele está com raiva de mim e diz que seu cliente HTTP vê todas as mensagens com status 500. Ele acha que sou idiota porque não consigo encontrar mensagem de erro com status 500. Como posso explicar a ele que axios não lida com mensagens de erro 500?

Na verdade, você deve ser capaz de lidar com o erro com status 500, pode verificar o status do http em resposta e decidir como lidar com isso no lado do cliente. Isso já está documentado neste link (https://github.com/axios/axios#handling-errors)

Aqui está como eu detecto o erro 500 do servidor e funciona para mim.

.catch(function (error) {
    var errorObj = JSON.parse(JSON.stringify(error));
    console.log(errorObj);
    if (errorObj.code == 'ECONNABORTED') {
        alert('Connection timed out.');
    }
});

Você pode lidar com 500 status independentemente, mas é uma prática muito ruim devolvê-lo propositalmente do lado do servidor, na minha opinião ...

Também estou recebendo error.response undefined, então tento o código abaixo.

axios.interceptors.response.use(function (response) {
  return response;
}, function (error) {
  // Do something with response error
  let {response} = error;
  // response?.status === 401 es7 way.
  if (response && response.status === 401) {
    // Do logout;
    // Redirect to login;
    return Promise.reject(error.response);
  } 
  else if (error.response){
    // Do something.
    console.log('some API_CLIENT error');
    return Promise.reject(error.response);
  }
 return Promise.reject(error);
});

Isso é muito ruim, o tratamento de erros é importante.

Como vai agora? Ainda estou tendo o mesmo problema com a versão 0.18.0!

mesmo problema para mim: @nuxtjs/axios v5.0.0

É um bug

Daniel Stern [email protected]于 2019 年 2 月 28 日 周四 04:39 写道 :

Deixe-me resumir esta discussão.

tl; dr:
TODOS A incapacidade de detectar erros de HTTP é um problema.
DESENVOLVEDORES Ser incapaz de detectar erros de HTTP não é um problema.

-
Você está recebendo isto porque comentou.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/axios/axios/issues/960#issuecomment-468020991 ou mudo
o segmento
https://github.com/notifications/unsubscribe-auth/AAN8CbMHohyuSZHYlcieD_5yUqizpkSYks5vRuzygaJpZM4N9Ljl
.

Você tem que mencionar este problema no README, por favor, muito útil. Obrigado!

https://github.com/axios/axios/issues/960#issuecomment -320659373

Concordando com outros cartazes. Ter um objeto com estrutura imprevisível dado a catch dependendo do ponto onde o erro acontece não é ótimo. Tanto error.response quanto JSON.stringify(error) podem errar dependendo da causa. A abordagem sugerida em https://github.com/axios/axios#handling -errors também não é exatamente esclarecedora sobre isso.

Ter que fazer todas essas acrobacias para retornar uma maldita mensagem de erro é constrangedor em 2019. Teria sido constrangedor em 1990. Sério, pessoal do JS, intensifiquem seu jogo. Aprenda um pouco do design da API e reconheça que suas 'decisões criativas' custam milhares de pessoas incontáveis ​​horas depurando uma bagunça que você está ignorando deliberadamente.

Para aqueles que lutam com as referências circulares, você pode fazer algo assim:

try {
// your axios request
} catch (error) {
  const { response } = error;
  const { request, ...errorObject } = response; // take everything but 'request'
  res.status(response.status);
  return res.json(errorObject); // or use 'return res.json(response.data.error);' then you don't need to omit the 'request'
}

Para aqueles que lutam com as referências circulares, você pode fazer algo assim:

try {
// your axios request
} catch (error) {
  const { response } = error;
  const { request, ...errorObject } = response; // take everything but 'request'
  res.status(response.status);
  return res.json(errorObject); // or use 'return res.json(response.data.error);' then you don't need to omit the 'request'
}

Obrigado cara! seu código funcionou bem para mim.

O problema está em "lib / core / enhanError". O objeto de solicitação é adicionado ao erro. Faz sentido adicionar resposta à resposta, pois há apenas um parâmetro nas APIs baseadas em promessa (a biblioteca de solicitações retorna o erro como primeiro parâmetro e a resposta como segundo). Mas não faz sentido adicionar todo o pedido. A alteração do código é muito simples https://github.com/geoblink/axios/pull/1/files
Eu poderia abrir pr para o branch principal se parecer importante (não estou fazendo isso, pois o problema foi encerrado)

você pode fazer um wrapper de função que você chamará toda vez que fizer solicitações

const api = async (uri, data) => {
  try {
    const { data: response } = await axios({
      url: domain + uri,
      method: 'POST',
      data,
    });

    return response.data;
  } catch (error) {
    throw error.response.data;
  }
};

Você provavelmente está atingindo um tempo limite, então, tente verificar se existe 'resposta' no erro

axios.get()
.then(function(done) {
   //fine and can get done.data
})
.catch(function(err) {
  //catch the error, check it has a response object with lodash 
  if(_.has(err, 'response') {
     console.log(error.response.status);  
     console.log(error.response.data);
 } 
 else {
    console.log("Most likely a server timeout or an internet connection error");
    console.log("error response property is undefined")
 }
}); 

Isso funcionou para mim. Obrigada

usar "error.response" não funciona, para mim. O problema ocorre quando eu desconectei o servidor de banco de dados e meu servidor web retornou o erro 500.

Guia Rede nas ferramentas de desenvolvimento

código de resposta: 500
corpo de resposta:

{
  "error": {
    "statusCode": 500,
    "name": "Error",
    "message": "read ETIMEDOUT",
    "code": "ETIMEDOUT",
    "errno": "ETIMEDOUT",
    "syscall": "read",
    "stack": "Error: read ETIMEDOUT\n    at exports._errnoException (util.js:1050:11)\n    at TCP.onread (net.js:582:26)"
  }
}

erro do console do Chrome:

Uncaught (in promise) Error: Request failed with status code 500
    at createError (createError.js:15)
    at settle (settle.js:18)
    at XMLHttpRequest.handleLoad (xhr.js:77)

versão

"axios": "^ 0.15.3"

MESMO AQUI...

Em minha experiência:

"Modifique de console.log (erro) para console.log (erro.response) na captura."

funcionou melhor com console.log (error.response.data) no catch.

axios.interceptors.response.use (nulo, erro => {
return error.response;
});

getClients: async (state) => {
const res = await axios.get ( ${BASE_API}/clients );
console.log ('res', res);
if (res) {
state.commit ("setClient", res.data);
}
}

Outra opção

/**
 * Whenever error.message is accessed we want to se the full API error message (JSON) if it's present
 * not just some generic http status code + message
 * see https://github.com/axios/axios/issues/960 for context
 *
 * <strong i="6">@param</strong> axios
 */
export function extractAPIErrorResponse(axios: AxiosInstance) {
    axios.interceptors.response.use(undefined, function (error: AxiosError) {
        (error as any).originalMessage = error.message;
        Object.defineProperty(error, "message", { get: function () {
            if (!error.response) {
                return (error as any).originalMessage;
            }
            return JSON.stringify(error.response.data);
        }});
        return Promise.reject(error);
    })
}

Experimentar{
Espere por isso. $ Axios .....
} pegar (e)
{
console.log (e)

}

axios.get("https://......") 
     .then( response => {
          return response
}).catch( () => {
         store.dispatch("errorComponentMethod")   // if there's an error, method is dispatched
})
//////////////////////////////////////
actions : {
      errorComponentMethod(){
              router.push("/errorComponent")     // method routes to error component
      }
}

Muito obrigado! Ajudou muito!

ainda tendo esse problema. no depurador do cromo a resposta está correta, mas axios retorna um "Request failed with status code 403" vez disso

Ainda estou tendo isso e estou muito confuso. Tentei entender os comentários acima - mas por que exatamente axios retorna indefinido quando há um erro?
try{ const res = await axios.get("someurl"); return res; } catch(e) { console.log(e); }
res é indefinido, embora o servidor esteja enviando de volta uma resposta com uma mensagem para POR QUE não funcionou. E não consigo obter esses dados ... por quê ??

** EDITAR: encontrei meu bug - nada de errado para mim com axios. Veja meu comentário dois comentários abaixo. Resumindo, meus interceptores não estavam passando os dados de erro de volta pelo pipeline do Axios, então eu estava sempre ficando indefinido.

@HoogsterInc Dê uma olhada nas definições de TypeScript aqui
você poderia fazer algo assim

try {
   axios.get(...)
} catch (error) {
   if (error.reponse) {
      // http status 4x, 5xx
   } else {
      // network error like timeout, connection refused etc...
   }
}

Obrigado pela resposta de tentar ajudar @konstantinblaesi - descobri meu problema.

Para mim eu tinha um interceptor configurado para verificar a autenticação do usuário, que caso ele não seja autenticado envia um código de erro específico. No entanto, eu não estava transmitindo os dados do erro quando o erro não correspondia a um código não autenticado ... suspiro ... erro bobo ruim. Portanto, após verificar o código de erro não autenticado, certifiquei-me de retornar Promise.reject (error); - Isso resolveu meu problema e os dados de erro já vêm completos.

Você pode usar err.toJSON()

catch((err) => {
    console.log(err.toJSON()); // Return error object
});

https://github.com/axios/axios#handling -errors

(definido para global)

no main.js

import axios from 'axios'

var instance = axios.create(
 { validateStatus: function (status) {
    return status < 600; #you can change this with another value
  }
 });

ou
(definido para particular)

  axios.post('/formulas/create', {
       name: "",
       parts: ""
  }, { validateStatus: function (status) {
          return status < 600; // Reject only if the status code is greater than or equal to 500
        }})
    .then( 
   (response) => { console.log(response) },
   (error) => { console.log(error) }
   );

Axios e captura de dados de resposta de erro 500

const log = console.log;

  updateData(options = {}, flag = false){
    let url = `/opapi/appDownloadGuide/update`;
    let message = '更新成功!';
    let errorMessage = '更新失败!';
    if (flag) {
      message = '添加成功!';
      errorMessage = '添加失败!';
      url = `/opapi/appDownloadGuide/add`;
    }
    axios
    .post(url, options)
    .then(res => {
      // ❓🤔️500 , 在这里拦不住呀?
      log(`res`, res, res.status);
      return res.data;
    })
    .then(json => {
      const {
        code,
        success,
        data,
        errorCode,
        errorHint,
      } = json;
      if(code === 200) {
        this.$message({
          type: 'success',
          message,
        });
        this.init();
      } else{
        this.$message({
          type: 'error',
          message: `${errorMessage}: ${errorHint ? errorHint : ""}`,
        });
      }
    })
    .catch(err => {
      // 👌在这里拦截 error data!
      log(`error.response`, err.response);
      const {
        data,
        status,
        statusText,
      } = err.response;
      this.$message({
        type: "error",
        message: `${statusText}-${status}: ${data || ""}`,
        // message: "不能重复创建",
      });
      console.error(`500 err`, err);
    });
  },

https://stackoverflow.com/questions/38798451/how-to-catch-and-handle-error-response-422-with-redux-axios

Eu tenho exatamente o mesmo ambiente. Experimente isto:

axios.post('/formulas/create', {
  name: "",
  parts: ""
})
.then(response => { 
  console.log(response)
})
.catch(error => {
    console.log(error.response)
});

_Modifique de console.log(error) para console.log(error.response) em catch _.

Você também pode usar um interceptor global e rejeitar apenas error.response . O problema é quando console.log tenta mostrar o erro, a representação da string é impressa, não a estrutura do objeto, então você não vê a propriedade .response .

Não funciona para mim

@ gopal-g isso é indefinido para mim.

@ gopal-g sim mesmo indefinido que estou recebendo.

Estou usando o Axios 0.19.2. Eu adicionei a solução de @konstantinblaesi :

Outra opção

/**
 * Whenever error.message is accessed we want to se the full API error message (JSON) if it's present
 * not just some generic http status code + message
 * see https://github.com/axios/axios/issues/960 for context
 *
 * <strong i="9">@param</strong> axios
 */
export function extractAPIErrorResponse(axios: AxiosInstance) {
    axios.interceptors.response.use(undefined, function (error: AxiosError) {
        (error as any).originalMessage = error.message;
        Object.defineProperty(error, "message", { get: function () {
            if (!error.response) {
                return (error as any).originalMessage;
            }
            return JSON.stringify(error.response.data);
        }});
        return Promise.reject(error);
    })
}

Isso funcionou para mim, muito obrigado @konstantinblaesi ! Não entendo por que o comportamento padrão do Axios não é assim - o comportamento padrão é eliminar a parte "mensagem" do erro original, que eu acho que é a parte mais importante!

Só para ficar claro, em meu aplicativo, meu servidor está retornando um erro 400 (que deve ser uma resposta):

% curl -X POST http://my-server/api -d '{"foo": "bar"}'
{"status": 400, "message": "missing param XYZ"}

e sem essa correção, recebo do Axios um objeto de erro que contém apenas name , stack , config (que contém a solicitação original) e nenhuma "resposta". Mas com essa correção, o erro contém a propriedade message correta do servidor.

Quanto ao motivo de não haver propriedade "resposta" sem essa correção, parece estar relacionado a settle em axios.js em torno da linha 1171:

        module.exports = function settle(resolve, reject, response) {
          var validateStatus = response.config.validateStatus;
          if (!validateStatus || validateStatus(response.status)) {
            resolve(response);
          } else {
            reject(createError(
              'Request failed with status code ' + response.status,
              response.config,
              null,
              response.request,
              response
            ));
          }
        };

e você pode ver que ele não passa por response.message ao criar o erro. Além disso, em meu aplicativo não vejo a resposta em error.response , essa propriedade não existe - eu não entendo isso. Mas de qualquer maneira, a correção acima funciona para mim.

Estou tentando detectar erros de validação do servidor.

Código:

axios.post('/formulas/create', {
       name: "",
       parts: ""
})
.then( 
  (response) => { console.log(response) },
  (error) => { console.log(error) }
);

Saída de registro do console

Error: Request failed with status code 422
    at createError (app.js:6765)
    at settle (app.js:29489)
    at XMLHttpRequest.handleLoad (app.js:6600)

Saída da guia de rede
{"nome": ["O campo do nome é obrigatório."], "partes": ["O campo das partes é obrigatório."]}

Devo estar vendo um objeto que contém a validação de formulário JSON, pois essa é a resposta na minha guia de rede, parece que recebo a saída de captura JS?

Também tentei o seguinte:

axios.post('/formulas/create', {
  name: "",
  parts: ""
})
.then(response => { 
  console.log(response)
})
.catch(error => {
    console.log(error)
});

Mesmo resultado

Mais pessoas parecem ter o mesmo problema usando o mesmo ambiente que eu aqui.
https://laracasts.com/discuss/channels/vue/issues-with-axios-catch-method

  • Versão Axios: ^ 0.16.2
  • VueJS 2.3.4
  • Vue-template-compiler 2.3.4
  • Laravel-mix
  • Ambiente: nó v6.4.0, chrome 58, Mac OSX 10.12.4

axios.post ('/ formulas / create', {
nome: "",
partes: ""
})
.então(
(resposta) => {console.log (resposta)},
) .catch (err => consol.log (err.response.data)});

error.response é um objeto, ele irá gerar [objeto, objeto] no log do console.
você deve usar error.reposne.data para acessar a mensagem de erro.
consulte: https://itnext.io/javascript-error-handling-from-express-js-to-react-810deb5e5e28

@chandukasm sim, mas no meu caso _não_ tenho um error.response - é indefinido, embora a solicitação tenha sido enviada e a resposta recebida por expresso. Veja também meu comentário acima; a mensagem é ignorada (substituída por uma mensagem genérica) mesmo quando existe uma resposta.

error.response é um objeto, ele irá gerar [objeto, objeto] no log do console.
você deve usar error.reposne.data para acessar a mensagem de erro.
consulte: https://itnext.io/javascript-error-handling-from-express-js-to-react-810deb5e5e28

se você vir [objeto, objeto] em console.log, basta fazer JSON.stringify (error.response) para ver o erro real.

Não há objeto error.response .

return this.$axios
  .post(postUrl, payload, { responseType: 'json' })
  .then(
    (response) => {
      this.message = `RESP: ${JSON.stringify(response)}`;
    },
    (reason) => {
      this.message = `REAS: ${JSON.stringify(reason)}`;
    }
  )
  .catch((err) => {
    this.message = `CATCH: ${JSON.stringify(err)}`;
  });

carga útil contém um valor inválido propositalmente para acionar HTTP 422, que no Postman funciona como esperado e o servidor (LB4) retorna um erro completo no formato JSON explicando onde os dados de entrada estavam errados, mas em axios, o objeto error.response é indefinido .

Esta página foi útil?
0 / 5 - 0 avaliações