← Blog
engineeringbackendarchitectureindie dev

Gli errori sono dati

20 marzo 2026

Gli errori sono dati

Il pattern di gestione degli errori più comune che vedo nei codebase in produzione è il catch block vuoto. Qualcosa lancia un'eccezione, la catturi, restituisci null o un array vuoto o niente. Il sistema continua a girare. Nessuno sa che qualcosa è andato storto.

Sembra una scelta difensiva. Non lo è. È così che avvengono i fallimenti silenziosi.

Gli errori sono informazioni

Un 404 ti dice che qualcuno ha seguito un link rotto. Un errore di validazione ti dice cosa stanno davvero inviando gli utenti. Un timeout ti dice dove le tue dipendenze sono lente. Un null inatteso ti dice che un'assunzione nel tuo codice è sbagliata.

Niente di tutto questo è qualcosa da nascondere. Sono segnali su quello che il tuo sistema sta facendo nel mondo reale, in condizioni reali, con utenti reali. L'istinto di sopprimerli è l'istinto di volare alla cieca.

Due tipi di errori

La maggior parte dei problemi di gestione degli errori nasce dal confondere due cose fondamentalmente diverse.

Gli errori operativi sono attesi. Un file non trovato. Un utente che invia dati non validi. Un'API di terze parti che restituisce un 503. Fanno parte del comportamento normale del sistema. Li gestisci con grazia, restituisci una risposta significativa e vai avanti. Non sono bug — sono casi che il tuo sistema dovrebbe sapere gestire.

Gli errori del programmatore non sono attesi. Un riferimento null dove null non dovrebbe mai esistere. Un'asserzione che dovrebbe sempre reggere. Un percorso di codice che non dovrebbe mai essere raggiunto. Questi non sono casi da gestire con grazia — sono casi da far emergere con rumore, perché qualcosa nel codice non va.

I catch block che trattano entrambi allo stesso modo sono la radice della maggior parte dei problemi di osservabilità. Gli errori operativi meritano handler. Gli errori del programmatore meritano rumore.

Cosa loggare, cosa propagare, cosa ignorare

Per gli errori operativi ai confini del sistema — endpoint API, handler di webhook, integrazioni esterne — loggo a livello info con abbastanza contesto per capire cosa è successo: l'input, l'errore, la risposta inviata. Non uno stack trace. Solo i fatti.

Per gli errori del programmatore, loggo tutto. Stack trace, contesto della richiesta, stato rilevante. Poi lascio propagare l'errore, o faccio crashare se è un job in background. Un processo che muore rumorosamente è più facile da correggere di uno che continua in uno stato corrotto.

C'è una terza categoria: errori che mi aspetto avvengano a una frequenza nota e su cui non devo agire. Un retry che riesce al secondo tentativo. Un cache miss. Questi li loggo a livello debug o li salto del tutto. Il rapporto segnale-rumore nei log è importante — se tutto è un errore, niente lo è.

La trappola del fallimento silenzioso

Gli errori più pericolosi non sono quelli che crashano il server. Sono quelli che non emergono affatto.

Una funzione che restituisce null invece di lanciare, un catch block che inghiotte un'eccezione e restituisce un default — questi permettono allo stato corrotto di viaggiare in profondità nel sistema. Quando ti accorgi che qualcosa non va, l'errore originale è sparito. Quello che rimane è un sintomo in un posto lontano dalla causa.

La soluzione è validare presto e fallire al confine. Non passare dati malformati nel sistema sperando che si sistemino a valle. Fai emergere il problema dove ha origine.

Osservabilità senza infrastruttura

Non hai bisogno di Datadog al giorno uno. Quello che ti serve sono log strutturati con abbastanza contesto per riprodurre il problema: un ID di errore cercabile, l'input che l'ha scatenato, e un timestamp. È la maggior parte di quello che ti dà uno stack di osservabilità completo, al costo di poche righe di codice di logging.

Ho debuggato problemi in produzione su Clover, su Barba Studio, su integrazioni con lo SDI italiano — quasi sempre leggendo log. Non dashboard, non trace distribuiti. Log con abbastanza contesto per capire cosa era successo.

Quando gli errori significano qualcosa

Trattare gli errori come dati invece che come eccezioni da sopprimere cambia come costruisci. Cominci a pensare a cosa ti dice ogni modalità di fallimento. Loggi con intenzione invece di loggare per copertura. Noti i pattern — certi errori che si raggruppano attorno a certi input, certe integrazioni che falliscono a certi ritmi.

Il sistema non diventa più silenzioso. Diventa più leggibile. E un sistema leggibile è uno che puoi effettivamente correggere.