2016-02-11 8 views
5

Ecco cosa ho incontrato. Da qualche parte in un Reagire funzione di rendering del componente, ho questo:Un errore generato da un componente React, catturato nel blocco catch di una promessa non correlata

{first_name} {last_name} 

ho sostituito con questo:

{first_name.toUpperCase()} {last_name.toUpperCase()} 

E la mia domanda non poteva più login sto usando Axios di parlare con il. backend. Axios è basato sulla promessa. E dopo ho fatto il cambiamento sopra. A quanto pare ha iniziato a eseguire sia il then sia il blocco catch della mia chiamata API login. Mentre stampo la risposta nel blocco catch.

function login(data, success, error) { 
    axios.post('/login', 
    JSON.stringify(data), 
    { 
     baseURL: config.apiUrl, 
     headers: { 'Content-Type': 'application/json; charset=utf-8' } 
    }) 
    .then((response) => success(response.data)) 
    .catch((response) => { 
    console.log(response) 
    error(response.status)}) 
} 

ottengo il seguente:

TypeError: Cannot read property 'toUpperCase' of undefined 

Non c'è assolutamente alcuna relazione tra la componente di cui sopra (si tratta di un componente muto semplice visualizzazione roba da puntelli nella pagina) e il codice API chiamando.

Questa non è la prima volta che ho riscontrato questo problema nella mia app. Qualcuno si è mai imbattuto in qualcosa di simile prima? Capisco che le mie variabili nel componente non sono definite, ed è per questo che l'errore si presenta. La mia domanda è: come si inserisce nel blocco delle promesse da qualche parte all'altro capo dell'app.

risposta

3

Così si scopre che in JavaScript, qualsiasi catch blocco prenderà qualsiasi errore che viene gettato in qualsiasi parte del codice. E questo è in base alla progettazione.

Ecco il spec:

La dichiarazione throw genera un'eccezione definita dall'utente. L'esecuzione di interromperà la funzione corrente (le istruzioni dopo il lancio non saranno eseguite ) e il controllo verrà passato al primo blocco catch nello stack di chiamate . Se non esiste un blocco catch tra le funzioni del chiamante, il programma terminerà.

Una soluzione è quella di utilizzare un gestore su tutte le promesse che si presento, che avrebbe console.log tutto ciò che non si aspettava, come questa:

export function apiErrorHandler(handler) { 
    return (error) => { 
    if (error.stack) { 
     throw error 
    } 
    if (error.status && error.data) { 
     handler(error) 
    } else { 
     console.error('Unknown type of error thrown during service request or its handler:', error) 
    } 
    } 
} 

e poi collegarlo al Axios servizio:

export function serviceGetContacts(success, error) { 
    axios.get(`/contacts`, cfg()) 
    .then((response) => success(response.data)) 
    .catch(apiErrorHandler(error)) 
} 
+0

Dato che questo è di progettazione, potresti fornire informazioni sul motivo per cui questo è il comportamento desiderato? –

+1

Questo è JavaScript. In base alla progettazione! = Comportamento desiderato.)) –

+0

Perché l'Axios chiama parte dello stack di chiamate del rendering di quel componente?Sto incontrando lo stesso problema di errbody else [qui] (https://github.com/mzabriskie/axios/issues/66) –

0

Le modifiche generano un errore TypeError se il nome o il cognome non sono ancora definiti. Che è piuttosto probabile prima che il processo di login sia completato.

Provare a utilizzare questo, invece:

{first_name && first_name.toUpperCase()} {last_name && last_name.toUpperCase()} 
+0

Ho aggiunto un chiarimento alla domanda, si prega di consultare l'ultimo paragrafo. –

Problemi correlati