Vai al contenuto
Design

Stati di errore nella UX: cosa mostrare quando una richiesta fallisce

Una richiesta può fallire in sei modi, dal campo rifiutato alla connessione persa. Cosa mostrare per ognuno, come rendere sicuro il riprova e cosa scrivere.

15 ottobre 2026 · 9 min di lettura

A dark form card on the left with a white button; a white line leaves the button, breaks into a dashed gap, then fans out into six quiet curves, each ending at a small dark screen lit in a different place: a field outline, a dialog, half of a split view, a countdown bar, a top banner, a single dot

Il percorso d'errore è tutto quello che un prodotto mostra quando una richiesta non va a buon fine: il messaggio, dove compare, cosa succede al lavoro appena fatto e l'azione che rimette l'utente al lavoro. Copre sei guasti diversi, dal campo che il server rifiuta alla connessione che cade a metà di un salvataggio. Ognuno chiede una schermata sua. Va progettato prima del lancio, perché in produzione il primo a incontrarlo è qualcuno nel mezzo di un compito, non un tester.

Perché il percorso d'errore decide la fiducia in un prodotto?

Un errore costa due volte: la richiesta persa e il tempo che serve per capire cos'è successo. I test di Baymard Institute sul checkout hanno rilevato che i messaggi d'errore inattesi contribuiscono all'abbandono dei form, e che il 31% dei siti analizzati non ha nessuna validazione inline. Il dato riguarda i checkout e-commerce. Un form SaaS che salva una fattura o invita un collega funziona allo stesso modo, e si abbandona allo stesso modo.

Il costo più duro è la fiducia. Chi ha perso dieci minuti di testo per un timeout ha un buon motivo per copiarlo altrove, la volta dopo, prima di premere Salva. E l'abitudine resta anche quando il bug non c'è più.

Perché «Qualcosa è andato storto» non basta?

La soluzione più rapida è un toast: Qualcosa è andato storto. Riprova. Non funziona per quattro motivi. Non dice la causa, quindi non si distingue un refuso da un guasto del server. Propone un'azione che può essere quella sbagliata: riprovare tre volte con una carta rifiutata dà tre volte la stessa risposta. Sparisce dopo pochi secondi, spesso prima che qualcuno l'abbia letto. E se non sta in una live region, chi usa uno screen reader non lo sente affatto.

La correzione comincia prima del testo. Ogni guasto ha una causa diversa, una cosa diversa che l'utente può fare e quindi un posto diverso sullo schermo.

Quali sono i sei modi in cui fallisce una richiesta?

Conviene raggruppare i guasti in base a cosa può fare l'utente subito dopo. Il codice di stato è solo il punto di partenza. Sei gruppi coprono quasi ogni richiesta di un prodotto SaaS.

  1. Dato rifiutato (400, 422). Il server ha scartato un valore, e l'utente può correggerlo. Il messaggio va accanto al campo, gli altri valori restano al loro posto e il focus passa al primo campo con l'errore.
  2. Sessione o permessi (401, 403). L'utente è uscito da un'altra scheda, oppure ha perso l'accesso. Può rientrare o chiedere i permessi. Lo si fa rientrare sul posto, in una finestra di dialogo, e poi si rimanda la richiesta: così il lavoro non va perso.
  3. Conflitto o elemento sparito (404, 409, 412). Qualcun altro ha modificato o cancellato il record. Prima di decidere, l'utente deve vedere cosa è cambiato. Si mostrano le due versioni, oppure si dice chiaro che l'elemento non c'è più e dove andare.
  4. Troppe richieste o server sovraccarico (429, 503). Il server chiede al client di rallentare, spesso con un header Retry-After. L'utente può solo aspettare. Si mostra quanto, con un conto alla rovescia, e si riprova in automatico.
  5. Errore del server (500, 502). Qualcosa non ha funzionato dall'altra parte. Si riprova una volta in automatico; se fallisce ancora, si mostra un codice di riferimento da mandare all'assistenza.
  6. Offline o timeout. La richiesta non ha avuto risposta, e l'utente non sa se è arrivata. L'azione resta in coda, il messaggio dice che partirà quando torna la connessione, e niente appare come salvato finché il server non lo conferma.

A distinguere i sei gruppi è una domanda che guida tutto il progetto: la richiesta ha cambiato qualcosa sul server? Per dati rifiutati, permessi e conflitti la risposta è no. Per un timeout la risposta onesta è che il client non lo sa, ed è il caso che chiede più attenzione.

Come si salva il lavoro dell'utente quando una richiesta fallisce?

Le linee guida di Nielsen Norman Group sui messaggi d'errore lo dicono in poche parole: conservare quello che l'utente ha inserito. Nel percorso d'errore diventa quattro regole.

  • Un form non si svuota mai dopo un errore. Si ripresenta con i valori digitati, compresi quelli che il server aveva accettato.
  • I testi lunghi (una descrizione, un messaggio, un form a più passi) si salvano nel browser mentre si scrive, così un ricaricamento o un crash li riporta indietro. Le nostre regole per i form lunghi trattano il salvataggio automatico più nel dettaglio.
  • Quando la sessione scade, si rientra da una finestra sopra la pagina. Un rimando alla pagina di login butta via il form.
  • Se l'interfaccia si è aggiornata in modo ottimistico (la riga è comparsa prima della risposta del server), la modifica si annulla in modo visibile e si spiega perché. Una riga che sparisce in silenzio sembra un dato perso.

Quando è sicuro mostrare il pulsante Riprova?

Un pulsante Riprova promette che premerlo due volte non farà la stessa cosa due volte. Per le letture è già così. Per le scritture vale solo se il server riconosce una ripetizione. L'API di Stripe lo fa con una chiave di idempotenza: il client manda una chiave unica con ogni creazione o modifica, Stripe salva la prima risposta legata a quella chiave e a ogni nuovo tentativo con la stessa chiave restituisce quella, invece di addebitare una seconda volta. Stripe conserva le chiavi per almeno 24 ore. Gli endpoint del tuo prodotto hanno bisogno dello stesso schema prima che l'interfaccia proponga di riprovare un pagamento, un invito o qualsiasi azione che manda un'email.

Anche i tentativi automatici vanno limitati. La Builders' Library di Amazon definisce i retry «egoisti»: quando un servizio fallisce perché è sovraccarico, ogni nuovo tentativo aggiunge carico e può peggiorare il guasto. Lo schema che consiglia è il backoff esponenziale con un tetto e con jitter: si aspetta di più dopo ogni tentativo, ci si ferma a un massimo e si aggiunge una quota casuale, così mille client non riprovano nello stesso secondo. Se il server manda Retry-After con un 429 o un 503, vale il suo numero (l'header è definito nella RFC 9110, lo stato 429 nella RFC 6585).

Nell'interfaccia seguiamo tre regole: un tentativo silenzioso su una lettura, nessuno su una scrittura senza chiave di idempotenza, e uno stato visibile per tutto quello che dura più di un paio di secondi.

Come si scrive un messaggio d'errore?

La griglia di valutazione di NN/g divide un buon messaggio in visibilità, comunicazione ed efficienza. Sullo schermo bastano due frasi: cosa è successo e cosa fare adesso.

  • La causa, con le parole di chi legge. La banca ha rifiutato la carta dice chi chiamare. Errore di pagamento 402 no.
  • Il passo successivo, come pulsante. Usa un'altra carta, Accedi di nuovo, Carica l'ultima versione. Un messaggio senza azione lascia l'utente a indovinare.
  • Nessuna colpa. NN/g sconsiglia parole come invalid, illegal e incorrect, che in italiano diventano «non valido», «non consentito», «errato». Questa data viene prima della data di inizio spiega. Data non valida rimprovera.
  • Un peso pari al danno. L'errore di un campo sta sotto il campo. Il salvataggio fallito di tutta la pagina merita un banner che resta finché l'utente non agisce. La pagina d'errore intera serve quando non funziona niente, e tiene comunque la navigazione, così si può uscire.
  • Un codice di riferimento per gli errori del server. Una sigla breve da incollare in un ticket trasforma «non va» in una riga di log che qualcuno può trovare.

Come si rende accessibile il percorso d'errore?

Un errore segnalato solo in rosso esclude chi non distingue i colori e chi non vede lo schermo. Le WCAG fissano il minimo. Il criterio 3.3.1 chiede che un errore rilevato sia identificato e descritto a parole. Il criterio 3.3.3 chiede un suggerimento per correggerlo, quando è noto. Il primo è di livello A, il secondo di livello AA: entrambi rientrano nel livello AA delle WCAG 2.1 che la norma EN 301 549 recepisce, come spieghiamo nell'articolo sull'European Accessibility Act.

Nel markup vuol dire:

  • aria-invalid="true" sul campo con l'errore e aria-describedby che punta al messaggio, così lo screen reader legge il messaggio insieme al campo.
  • Una live region (role="alert" per i guasti urgenti, aria-live="polite" per gli altri) per gli errori che compaiono senza ricaricare la pagina, come descrive la documentazione MDN sul ruolo alert.
  • Un'icona o un'etichetta accanto al colore, così lo stato si legge anche in scala di grigi.
  • Il focus sul primo campo con l'errore, o sul banner, dopo un invio fallito.

Come appare il percorso d'errore su una schermata sola?

Un caso a titolo d'esempio: in un gestionale di fatturazione B2B qualcuno modifica una fattura e preme Salva. Ecco la stessa schermata nei sei guasti.

  • La partita IVA è scritta male (422). Il campo passa allo stato d'errore con Alla partita IVA manca il prefisso del paese, per esempio IT o ES, il focus ci si sposta e gli altri campi restano compilati.
  • La sessione è scaduta un'ora fa (401). Sopra la fattura si apre una finestra di accesso. Dopo il login il salvataggio parte con la stessa chiave di idempotenza.
  • Nel frattempo una collega ha cambiato la scadenza (409). Un banner dice Anna ha spostato la scadenza al 30 novembre mentre modificavi e propone Tieni la mia o Usa la sua.
  • L'API ha raggiunto il limite (429, Retry-After: 20). Il pulsante diventa Salvo tra 20 s e fa il conto alla rovescia. Nessun clic richiesto.
  • Il server risponde 500. Un tentativo automatico con la stessa chiave. Se fallisce anche quello, un banner dice Non siamo riusciti a salvare la fattura. Le modifiche sono ancora qui. con Riprova e un codice di riferimento.
  • Il portatile perde il Wi-Fi. Sulla fattura compare Non ancora salvata. La salviamo appena torni online. e il titolo della scheda porta un segno finché il salvataggio non arriva.

Sei stati, un componente. In un design system sono varianti dello stesso form e dello stesso banner, ed è per questo che li disegniamo nello stesso file del flusso principale, invece di lasciarli a un ticket dopo il lancio. Lo stesso ragionamento vale per la schermata prima che esistano dati, di cui parliamo in empty state: i 4 stati che ogni schermata deve prevedere.

Domande frequenti

Articoli correlati

Studio

Inizia un progetto.

Scriviamo riguardo a ciò che costruiamo. Raccontaci cosa vuoi costruire tu.