modulo 12 di 24 / Ore 21-40

Moduli 9-16 / Checkpoint 40 ore

Trasformare errori tecnici in messaggi utente

Come implementare nel Registro la traduzione di errori tecnici in messaggi comprensibili: funzione traduciErrore, dizionario messaggi e gestione degli errori non previsti.

25 min Architettura del software

Trasformare errori tecnici in messaggi utente

Questa lezione appartiene al Modulo 12 — Errori comprensibili.

Obiettivo della lezione

Implementare nel Registro la funzione traduciErrore che converte i codici di errore tecnici in messaggi italiani leggibili, gestisce i codici non previsti con un fallback sicuro e mantiene il dettaglio tecnico nei log.

Alla fine l’utente non vede mai Cannot read properties of undefined o STRUMENTO_GUASTO_NON_PRESTABILE — vede “Questo strumento è guasto e non può essere prestato.”

Perché serve nel percorso

I codici errore del dominio (STRUMENTO_NON_TROVATO, PRESTITO_GIA_CHIUSO) sono ottimi per il codice — sono precisi, verificabili nei test, facili da cercare con grep. Ma sono incomprensibili per un docente o un tecnico che usa il Registro. La traduzione è un compito esplicito della UI.

Nel Registro del laboratorio

La funzione traduciErrore:

// src/presentation/traduciErrore.js
export function traduciErrore(codice) {
  const dizionario = {
    // Errori di strumento
    STRUMENTO_NON_TROVATO:
      "Lo strumento cercato non è presente nel registro.",
    STRUMENTO_GUASTO_NON_PRESTABILE:
      "Questo strumento è guasto e non può essere prestato. Segnala il problema al tecnico.",
    STRUMENTO_GIA_IN_PRESTITO:
      "Questo strumento è già in prestito a qualcun altro.",
    STRUMENTO_IN_MANUTENZIONE_NON_PRESTABILE:
      "Questo strumento è in manutenzione e non è disponibile al momento.",
    STRUMENTO_NON_DISPONIBILE:
      "Questo strumento non è disponibile al momento.",

    // Errori di prestito
    PRESTITO_NON_TROVATO:
      "Il prestito cercato non è presente nel registro.",
    PRESTITO_GIA_CHIUSO:
      "Questo prestito è già stato chiuso in precedenza.",

    // Errori di validazione
    NOME_STRUMENTO_NON_VALIDO:
      "Il nome dello strumento deve avere almeno 2 caratteri.",
    NOME_STRUMENTO_TROPPO_LUNGO:
      "Il nome dello strumento non può superare 80 caratteri.",
    CATEGORIA_NON_VALIDA:
      "La categoria selezionata non è valida.",
    STUDENTE_ID_MANCANTE:
      "Inserisci l'identificativo dello studente prima di registrare il prestito.",

    // Errori di infrastruttura
    SALVATAGGIO_FALLITO:
      "Impossibile salvare i dati. Verifica che il browser supporti il salvataggio locale.",
    LETTURA_FALLITA:
      "Impossibile leggere i dati. Prova a ricaricare la pagina."
  };

  if (codice in dizionario) {
    return dizionario[codice];
  }

  // Fallback per errori non previsti
  console.error("[ERROR] codice_errore_non_tradotto", { codice });
  return "Si è verificato un errore imprevisto. Se il problema persiste, contatta il tecnico.";
}

Come si usa nella UI:

// src/presentation/azioniPrestito.js
try {
  registraPrestito({ strumentoId, studenteId }, archivioStrumenti, archivioPrestiti);
  mostraMessaggio(elementoUI, "Prestito registrato correttamente.", "successo");
} catch (err) {
  // err.message contiene il codice tecnico ("STRUMENTO_GUASTO_NON_PRESTABILE")
  // traduciErrore lo converte in italiano
  mostraMessaggio(elementoUI, traduciErrore(err.message), "errore");
}

Procedura guidata

  1. Crea src/presentation/traduciErrore.js.
  2. Elenca tutti i codici errore che il Registro può lanciare (grep -r "throw new Error" src/).
  3. Per ogni codice: scrivi un messaggio in italiano comprensibile per un docente.
  4. Aggiungi il fallback per i codici non previsti.
  5. Sostituisci tutti i punti della UI che mostrano err.message direttamente con traduciErrore(err.message).

Attività in classe

Scrivi i messaggi italiani per questi codici errore:

## Dizionario messaggi

STRUMENTO_NON_TROVATO →

STRUMENTO_GUASTO_NON_PRESTABILE →

PRESTITO_GIA_CHIUSO →

NOME_STRUMENTO_NON_VALIDO →

STUDENTE_ID_MANCANTE →

Poi testa la funzione con un codice non nel dizionario:

console.log(traduciErrore("CODICE_INVENTATO"));
// deve restituire il messaggio di fallback
// non deve lanciare un errore

Spiegazione guidata per studiare

Il dizionario di traduzione è posizionato nella UI per una ragione precisa: il dominio parla in codici neutrali, la UI parla in italiano. Se metti la traduzione nel dominio, il dominio dipende dalla lingua dell’interfaccia — e domani non puoi fare una versione inglese senza modificare il dominio.

Il fallback è obbligatorio. In un progetto reale, ci saranno sempre codici errore non ancora nel dizionario — errori da librerie, errori imprevisti di infrastruttura, errori aggiunti dopo. Il fallback protegge l’utente da messaggi tecnici e ti avvisa (via console.error) che c’è un codice mancante.

Come aggiungere un nuovo codice:

  1. Il dominio o l’infrastruttura lancia throw new Error("NUOVO_CODICE").
  2. Il log in console segnala codice_errore_non_tradotto { codice: "NUOVO_CODICE" }.
  3. Tu aggiungi NUOVO_CODICE: "messaggio italiano" al dizionario.

Non serve modificare nessun altro file — il dizionario è il punto centralizzato di traduzione.

Test della funzione traduciErrore:

// test/presentation/traduciErrore.test.js
import { traduciErrore } from "../../src/presentation/traduciErrore.js";

test("traduce STRUMENTO_NON_TROVATO in italiano", () => {
  const messaggio = traduciErrore("STRUMENTO_NON_TROVATO");
  expect(messaggio).toContain("non è presente"); // non è il codice tecnico
  expect(messaggio).not.toContain("STRUMENTO_NON_TROVATO"); // no codici in UI
});

test("restituisce il fallback per codici non nel dizionario", () => {
  const messaggio = traduciErrore("CODICE_SCONOSCIUTO");
  expect(typeof messaggio).toBe("string");
  expect(messaggio.length).toBeGreaterThan(10); // non è stringa vuota
});

test("non lancia eccezioni per nessun input", () => {
  expect(() => traduciErrore(undefined)).not.toThrow();
  expect(() => traduciErrore(null)).not.toThrow();
  expect(() => traduciErrore("")).not.toThrow();
});

Passo per passo nel progetto

  1. Esegui grep -rn "throw new Error" src/ e raccogli tutti i codici errore.
  2. Crea src/presentation/traduciErrore.js con il dizionario completo.
  3. Aggiungi il fallback con console.error per i codici non previsti.
  4. Scrivi i test (almeno 3: codice noto, codice sconosciuto, input anomalo).
  5. Aggiorna tutti i handler della UI per usare traduciErrore.
  6. Verifica nella pagina che nessun codice tecnico appare nell’interfaccia.

Prova di comprensione

  • Perché la funzione traduciErrore sta nella UI e non nel dominio?
  • Cosa succede se aggiungi un nuovo errore nel dominio ma dimentichi di aggiornare il dizionario?
  • Come testi che traduciErrore non lancia eccezioni per input imprevisti?
  • Qual è il vantaggio di avere un dizionario centralizzato invece di messaggi sparsi nella UI?

Errori da evitare

  • mostrare err.message direttamente in UI — espone codici tecnici incomprensibili;
  • mettere i messaggi italiani nei casi d’uso — il dominio non dipende dalla lingua della UI;
  • dimenticare il fallback — un codice non tradotto mostrerebbe stringa vuota o undefined;
  • non testare il fallback — potrebbe lanciare un’eccezione per input null/undefined.

Prodotto da consegnare

Il file src/presentation/traduciErrore.js con il dizionario completo di tutti i codici errore del Registro, il fallback sicuro, e i test. Nessun codice tecnico visibile nella UI durante l’uso normale.

Checklist di chiusura

  • traduciErrore.js esiste in src/presentation/
  • tutti i codici errore del Registro sono nel dizionario
  • il fallback non lancia eccezioni e logga il codice mancante
  • nessun handler della UI usa err.message direttamente
  • i test coprono: codice noto, codice sconosciuto, input anomalo
  • la UI non mostra mai codici tecnici durante l’uso normale

Risultato atteso

Ho creato traduciErrore.js con 12 codici errore del Registro tradotti in italiano.
Il fallback gestisce i codici non previsti e logga l'evento nella console.
Ho aggiornato tutti gli handler della UI per usare traduciErrore.
I test verificano: traduzione corretta, fallback sicuro, nessuna eccezione per input anomali.
L'utente vede messaggi in italiano — mai codici tecnici.