modulo 18 di 24 / Ore 41-60
Moduli 17-24 / Checkpoint 60 ore
Messaggi troppo dettagliati e informazioni tecniche
Riconoscere quando un messaggio contiene troppi dettagli tecnici e imparare a separare il messaggio per l'utente dal dettaglio tecnico per chi mantiene il sistema.
Messaggi troppo dettagliati e informazioni tecniche
Questa lezione appartiene al Modulo 18 — Sicurezza di base.
Il problema
Un messaggio troppo dettagliato rivela all’utente informazioni che non servono a lui ma che potrebbero essere utili a qualcuno con intenzioni malevole — o semplicemente confondere chi non è tecnico.
Esempi di messaggi troppo dettagliati nel Registro:
❌ "TypeError: Cannot read properties of undefined (reading 'stato')"
❌ "localStorage.getItem('registro:strumenti') ha restituito null"
❌ "STRUMENTO_NON_TROVATO: id=str-042 non presente in archivio"
❌ "Errore SQL: UNIQUE constraint failed: strumenti.id"
Nessuno di questi aiuta l’utente a capire cosa fare. Tutti rivelano dettagli sull’implementazione interna.
La distinzione fondamentale
Ogni errore ha due “destinatari” con bisogni diversi:
| Destinatario | Cosa gli serve | Dove va |
|---|---|---|
| Utente | Cosa è andato storto e cosa può fare | Visibile nella UI |
| Sviluppatore | Dettaglio tecnico per diagnosticare | console.error, log |
Il messaggio per l’utente deve essere comprensibile e azionabile. Il dettaglio tecnico deve essere preciso e conservato, ma non visibile.
Messaggi tipici nel Registro — prima e dopo
Strumento non trovato
// ❌ Troppo tecnico
mostraMessaggio("STRUMENTO_NON_TROVATO: id=str-042");
// ✅ Comprensibile
mostraMessaggio("Strumento non trovato. Controlla l'ID e riprova.");
console.error("Strumento non trovato nell'archivio", { strumentoId: "str-042" });
Salvataggio fallito
// ❌ Troppo tecnico
mostraMessaggio("QuotaExceededError: localStorage quota exceeded");
// ✅ Comprensibile
mostraMessaggio("Non riesco a salvare i dati. Prova a liberare spazio nel browser.");
console.error("localStorage pieno", errore);
Regola di dominio violata
// ❌ Troppo tecnico (codice errore esposto)
mostraMessaggio("STRUMENTO_GIA_IN_PRESTITO");
// ✅ Comprensibile
mostraMessaggio("Questo strumento è già in prestito e non può essere prestato di nuovo.");
// nessun console.error — non è un errore tecnico, è una regola del laboratorio
Errore JavaScript non gestito
// ❌ Mostra lo stack trace in console E nella UI
alert(errore.stack);
// ✅ Messaggio generico per l'utente, dettaglio in console
mostraMessaggio("Si è verificato un problema. Ricarica la pagina e riprova.");
console.error("Errore non gestito:", errore);
Come costruire la separazione
// Dizionario messaggi — nella Presentation
const messaggiUtente = {
STRUMENTO_NON_TROVATO: "Strumento non trovato. Controlla l'ID e riprova.",
STRUMENTO_NON_DISPONIBILE: "Questo strumento non può essere prestato al momento.",
STRUMENTO_GIA_IN_PRESTITO: "Questo strumento è già in prestito.",
STRUMENTO_GUASTO_NON_PRESTABILE: "Questo strumento è guasto e non può essere prestato.",
ARCHIVIO_NON_DISPONIBILE: "Non riesco a salvare i dati. Riprova tra poco.",
NOME_NON_VALIDO: "Il nome deve avere almeno 2 caratteri.",
CATEGORIA_MANCANTE: "Seleziona una categoria."
};
function gestisciErrore(errore) {
const messaggioUtente = messaggiUtente[errore.message];
if (messaggioUtente) {
// Errore atteso — mostra messaggio comprensibile
mostraAvviso(messaggioUtente);
} else {
// Errore inatteso — messaggio generico per l'utente, dettaglio in console
mostraAvviso("Si è verificato un problema. Riprova tra poco.");
console.error("Errore non gestito:", errore);
}
}
// Uso nel gestore di eventi
try {
await registraPrestito(comando);
} catch (errore) {
gestisciErrore(errore);
}
Cosa NON deve mai apparire nella UI
- Stack trace (
at function.js:42) - Codici errore interni (
STRUMENTO_NON_TROVATO) - Nomi di file o funzioni del codice
- Query o chiavi di localStorage
- Valori di variabili interne
Queste informazioni appartengono al log — non alla UI.
Procedura guidata
- Cerca tutti i blocchi
catchnel tuo progetto. - Per ogni
catch: cosa viene mostrato all’utente? È comprensibile? - Aggiungi
console.errorper conservare il dettaglio tecnico. - Sostituisci il messaggio grezzo con uno del dizionario
messaggiUtente. - Aggiungi un fallback per errori non previsti (
"Si è verificato un problema").
Attività in classe
## Messaggi nel mio Registro
Blocco catch analizzato (file e riga):
Messaggio attuale mostrato all'utente:
È comprensibile per un non-tecnico (sì/no):
Messaggio proposto:
Il dettaglio tecnico viene conservato (console.error) (sì/no):
Spiegazione guidata per studiare
La separazione tra messaggio utente e dettaglio tecnico è un principio di sicurezza e di qualità insieme. Da un lato, non riveli informazioni sull’implementazione. Dall’altro, chi usa il sistema capisce cosa fare.
Il punto centrale è: il codice errore appartiene al log, non alla UI. STRUMENTO_NON_TROVATO è un’etichetta interna precisa — utile per il debugging, non per l’utente. L’utente ha bisogno di “Strumento non trovato. Controlla l’ID.” — una frase che descrive il problema e suggerisce un’azione.
Il rischio tipico è usare alert(errore.message) perché è veloce. Funziona in sviluppo. In produzione espone l’implementazione e confonde l’utente.
Passo per passo nel progetto
- Apri tutti i file della
presentation/. - Cerca
alert,innerHTML = errore,textContent = errore.messageo simili. - Per ogni occorrenza: sostituisci con il messaggio dal dizionario.
- Aggiungi
console.errornello stesso blocco per conservare il dettaglio. - Verifica che il dizionario
messaggiUtentecopra tutti i codici errore che il progetto genera.
Esempio da leggere lentamente
// Confronto — stesso errore, due gestioni diverse
// ❌ Prima
catch (errore) {
document.getElementById("msg").textContent = errore.message;
// L'utente vede: "STRUMENTO_NON_TROVATO"
}
// ✅ Dopo
catch (errore) {
const messaggi = {
STRUMENTO_NON_TROVATO: "Strumento non trovato. Controlla l'ID.",
ARCHIVIO_NON_DISPONIBILE: "Impossibile salvare. Riprova tra poco."
};
const testo = messaggi[errore.message] ?? "Si è verificato un problema.";
document.getElementById("msg").textContent = testo;
// Dettaglio tecnico conservato nel log
if (!messaggi[errore.message]) console.error("Errore non previsto:", errore);
}
Prova di comprensione
- Elenca tre messaggi nel tuo Registro che un utente non tecnico non capirebbe.
- Per ognuno: quale messaggio mostreresti invece?
- Dove conserveresti il dettaglio tecnico?
Errori da evitare
- mostrare
errore.messagedirettamente nella UI; - usare
alert()con codici errore interni; - eliminare il dettaglio tecnico invece di spostarlo nel log;
- scrivere un messaggio generico per tutti gli errori senza distinzione (impossibile diagnosticare).
Prodotto da consegnare
Può essere:
- un dizionario
messaggiUtentecompleto con tutti i codici errore del progetto; - tre blocchi
catchrivisti con messaggio comprensibile +console.error; - un test manuale documentato: provoca un errore noto, verifica che l’utente veda il messaggio corretto.
Checklist di chiusura
- Nessun blocco
catchmostraerrore.messageo stack trace direttamente nella UI - Esiste un dizionario che mappa codici errore a messaggi comprensibili
- Tutti i blocchi
catchhannoconsole.errorper conservare il dettaglio tecnico - Gli errori non previsti mostrano un messaggio generico (non un codice)
- Ho verificato il comportamento provocando almeno un errore noto
Domande per la revisione
- Hai trovato messaggi tecnici nella UI? Quanti?
- Il dizionario
messaggiUtentecopre tutti i casi del tuo progetto? - Come distingui un errore “previsto” (che hai gestito) da uno “non previsto”?
Risultato atteso
Alla fine lo studente deve saper dire:
Nel mio Registro, i messaggi mostrati all'utente sono comprensibili:
- [errore X] → "[messaggio utente]"
- [errore Y] → "[messaggio utente]"
Il dettaglio tecnico viene conservato in console.error.
Gli errori non previsti mostrano: "Si è verificato un problema. Riprova tra poco."
Se questa spiegazione non è possibile, la lezione non è ancora davvero conclusa.