
Un errore 500 Internal Server Error è il server che gestisce il sito che ammette che qualcosa è andato storto nel suo codice, e che non può mostrarti la pagina per questo motivo. Non “la pagina non esiste”, non “non sei autorizzato”, non “torna più tardi” - solo un onesto e poco utile “qualcosa si è rotto qui dentro, e non è colpa tua.”
La parola da notare è internal. Il server sta parlando di sé stesso, non di una rete, un’autorizzazione, o qualcosa che hai fatto tu. Ha eseguito la tua richiesta, ha incontrato un errore che non sapeva come gestire, e l’unica cosa veritiera da dire era 500. Per questo il messaggio è così vago: il server non sta nascondendo i dettagli per essere difficile, sta rifiutando di esporre i suoi interni a uno sconosciuto.
Perché non ti dice nulla
Un 500 è l’errore più generico del web appositamente. Quando un’applicazione fallisce in un modo che non ha previsto - un’eccezione non catturata, una query che è andata in crash, un nil dove era atteso un oggetto - la cosa sicura da mostrare al mondo esterno è un muro vuoto. I dettagli di quello che è rotto, lo stack trace, il numero di riga, la query che è fallita, tutto rimane sul server, in un log, dove solo le persone che gestiscono il sito possono leggerlo.
Quindi il 500 che vedi e il motivo per cui è successo vivono in due posti diversi. Il browser ha il codice; il server ha la causa. Questo divario è l’intera difficoltà di un 500, ed è per questo che “ho ricevuto un 500” è un report che dice a uno sviluppatore quasi nulla da solo.
500 contro 502 e 504, che sembrano uguali da fuori
Tutti e tre fanno parte della famiglia del server “qualcosa è andato storto dalla nostra parte”, e distinguerli punta a cause molto diverse.
- 500 Internal Server Error
- L'applicazione ha eseguito e il suo codice ha fallito - un'eccezione non gestita, un crash all'interno della richiesta. Il server ha risposto; la risposta era un errore che ha fatto lui stesso
- 502 Bad Gateway
- Un server di prima linea ha ricevuto una risposta inutilizzabile dall'applicazione dietro di esso - crash, rifiuto, malformato. Il fallimento è tra due server
- 504 Gateway Timeout
- L'applicazione non ha risposto affatto nel tempo consentito. Il server di prima linea ha rinunciato ad aspettare
In breve: un 500 è l’applicazione che fallisce mentre è in esecuzione, un 502 è un proxy che non riesce a ottenere una buona risposta da essa, e un 504 è l’applicazione che è troppo lenta a rispondere. Se hai ricevuto un 500, il codice è stato eseguito e si è rotto; se hai ricevuto un 502 o 504, spesso non ha mai finito di essere eseguito affatto. Questa distinzione è la prima cosa che vale la pena sapere, perché decide se guardi nei log dell’applicazione o nell’infrastruttura di fronte a loro.
Se sei il visitatore
Ricarica una volta, perché un buon numero di 500 è un singolo momento negativo - una richiesta che ha subito una race condition, una query che è andata in timeout sotto una raffica - e il tentativo successivo atterra da qualche parte di sano. Se scompare, non c’è nulla da inseguire.
Se persiste, la colpa è dalla parte del sito, e genuinamente non c’è nulla nel tuo browser che raggiunga un bug nel loro codice. Cancellare la cache, provare in incognito, cambiare browser - nulla di ciò tocca il server, e ognuno è un comune mezz’ora spesa a trattare un 500 come se fosse un problema che potresti risolvere dal tuo posto. L’unica cosa utile che puoi fare è dirgli, con abbastanza dettagli in modo che possano trovare la riga corrispondente nel loro log: cosa stavi facendo, e approssimativamente quando.
Se è il tuo sito
Un 500 significa che il tuo codice ha lanciato qualcosa che non ha gestito, quindi la domanda è solo quale, e la risposta è nei tuoi log piuttosto che nella risposta che l’utente ha visto. Poche cause rappresentano la maggior parte di essi.
Un’eccezione non gestita nella richiesta. Di gran lunga la più comune. Un metodo chiamato su un nil, una chiave che non c’era, un tipo che non era quello che il codice assumeva. La richiesta ha raggiunto il tuo codice, il tuo codice ha lanciato, e nulla l’ha catturata. Il log dell’applicazione ha lo stack trace; il 500 dell’utente no.
Una chiamata al database non riuscita. Una query su una colonna che è stata rinominata, un pool di connessioni esausto sotto carico, una migrazione che è stata eseguita su un server e non su un altro. Questi spesso arrivano in raffiche, perché traccia il carico o un deploy piuttosto che un singolo input.
Un problema di configurazione o ambiente. Una variabile di ambiente mancante, un secret che non è stato impostato, un servizio che l’app si aspetta di raggiungere e non può. Questi sono quelli che trasformano ogni richiesta in un 500 tutto in una volta, di solito subito dopo un deploy o un cambio di infrastruttura, e sembrano allarmanti proprio perché nulla nel codice è cambiato - il terreno sotto di esso sì.
Un deploy difettoso. Codice nuovo che si solleva su un percorso che i test non hanno coperto, o avvia su uno schema che non esiste ancora. Se i 500 sono iniziati in una release, è il primo posto da guardare, e un rollback è più veloce di una diagnosi.
Il motivo per cui un 500 è così difficile da rintracciare in seguito
L’errore che l’utente ha visto non porta alcuna causa, quindi un 500 segnalato un’ora dopo, da memoria, è quasi inutile: hai un codice generico e un tempo approssimativo, e stai cercando in un log un ago che puoi solo descrivere come “circa le tre”. Lo stack trace che avrebbe denominato il bug è in una riga di log che nessuno ha catturato rispetto alla richiesta che l’ha prodotto.
Ciò che chiude un 500 rapidamente è la richiesta che l’ha causato, il suo tempo esatto, e cosa stava facendo la persona - catturato mentre è successo, quindi puoi abbinarlo alla riga di log che ha il vero errore in essa. Questa è la differenza tra un bug che trovi in un minuto e un log che scorri per un pomeriggio.
Session Replay
Estensione Chrome gratuita. Un clic sulla pagina che non funziona correttamente acquisisce lo screenshot, la console e il log di rete, e ti consegna un collegamento da incollare nel ticket.
Il log di rete contiene la richiesta non riuscita con il suo 500 e il momento esatto in cui è successo, quindi chiunque prenda il report può allinearlo con il log del server e leggere il vero errore - piuttosto che riprodurre tutto prima per scoprire cosa un codice generico stava nascondendo.
In un paragrafo
Un errore 500 Internal Server Error significa che l’applicazione ha eseguito la tua richiesta e il suo codice ha fallito in un modo che non ha gestito, quindi ha mostrato l’unica risposta generica sicura che aveva - il che è quello che lo rende diverso da un 502, dove un proxy non poteva ottenere una buona risposta dall’app, e un 504, dove l’app era troppo lenta a rispondere affatto. Se stai visitando, ricarica una volta e poi assumi che sia dalla loro parte. Se è tua, la causa è nei tuoi log, non nella risposta: sospetta un’eccezione non gestita, una query non riuscita, una configurazione mancante, o l’ultimo deploy - e cattura la richiesta non riuscita mentre ce l’hai, perché un 500 non ti dice nulla da solo.