modulo 10 di 24 / Ore 21-40

Moduli 9-16 / Checkpoint 40 ore

Gestire dati mancanti, vecchi o corrotti

Rendere l'infrastruttura piu robusta quando localStorage contiene dati mancanti, vecchi, incompleti o non validi.

30 min Architettura del software

Gestire dati mancanti, vecchi o corrotti

Quando leggiamo da localStorage, non possiamo fidarci completamente dei dati.

Potrebbero essere:

  • assenti;
  • vuoti;
  • non JSON;
  • vecchi;
  • incompleti;
  • modificati a mano;
  • incompatibili con il dominio attuale.

Infrastructure deve gestire questi casi senza far esplodere tutta l’applicazione con errori incomprensibili.

Obiettivo

Alla fine devi avere una strategia semplice per:

  • dati mancanti;
  • JSON non valido;
  • DTO incompleti;
  • versioni vecchie dei dati;
  • errore tecnico trasformato in errore gestibile.

Dato mancante

Se la chiave non esiste:

localStorage.getItem(CHIAVE_STRUMENTI)

restituisce:

null

Strategia:

if (!testo) {
  return [];
}

Archivio vuoto non e un errore.

E uno stato normale.

JSON corrotto

Se localStorage contiene:

questo non e JSON

JSON.parse lancia un errore.

Versione piu robusta:

function leggiJsonArray(chiave) {
  const testo = localStorage.getItem(chiave);

  if (!testo) {
    return [];
  }

  try {
    const dati = JSON.parse(testo);
    return Array.isArray(dati) ? dati : [];
  } catch {
    return [];
  }
}

Questa scelta evita il crash.

In una versione piu avanzata potremmo anche registrare un log tecnico.

DTO incompleto

Esempio:

{
  id: "s-001",
  nome: "Arduino Uno"
}

Mancano:

  • categoria;
  • stato.

Possibili strategie:

  1. scartare il dato;
  2. usare valori predefiniti;
  3. mostrare errore;
  4. migrare il dato.

Nel corso scegliamo una strategia semplice e dichiarata.

Per esempio:

se un DTO non e valido, lo scartiamo e lo segnaliamo nei log tecnici

oppure:

se manca lo stato, usiamo disponibile solo per dati demo

Non inventare regole senza scriverle.

Dati vecchi

Prima versione:

{ id: "s-001", nome: "Arduino Uno", stato: "disponibile" }

Nuova versione:

{
  versione: 2,
  id: "s-001",
  nome: "Arduino Uno",
  categoria: "microcontrollori",
  stato: "disponibile"
}

I dati vecchi non hanno categoria.

Se vogliamo leggerli, serve una migrazione.

Migrazione minima

Esempio:

function normalizzaStrumentoDto(dto) {
  return {
    id: dto.id,
    nome: dto.nome ?? dto.name ?? "Senza nome",
    categoria: dto.categoria ?? "senza categoria",
    stato: dto.stato ?? "disponibile",
  };
}

Questa funzione deve stare in Infrastructure.

Non nel dominio.

Attenzione: i valori predefiniti devono essere una scelta consapevole.

Errore tecnico e messaggio utente

Se localStorage contiene dati corrotti, l’utente non deve vedere:

Unexpected token q in JSON at position 0

Possibile messaggio:

Non riesco a leggere i dati salvati. Il registro verra avviato vuoto.

Oppure, in versione essenziale:

Dati salvati non leggibili.

La gestione completa degli errori verra ripresa nel modulo 12.

Qui basta non far arrivare errori tecnici grezzi all’utente.

Implementazione robusta minima

function leggiListaDaLocalStorage(chiave) {
  const testo = localStorage.getItem(chiave);

  if (!testo) {
    return [];
  }

  try {
    const dati = JSON.parse(testo);
    return Array.isArray(dati) ? dati : [];
  } catch {
    return [];
  }
}

Poi:

function leggiStrumenti() {
  return leggiListaDaLocalStorage(CHIAVE_STRUMENTI)
    .map(normalizzaStrumentoDto)
    .map(dtoToStrumento);
}

Se dtoToStrumento puo lanciare errori, devi decidere se scartare il singolo elemento o bloccare tutta la lettura.

Esercizio

Prova questi casi:

1. chiave localStorage assente
2. chiave presente ma contenuto non JSON
3. JSON valido ma non array
4. array con uno strumento incompleto
5. array con stato non valido

Per ogni caso scrivi:

  • cosa succede ora;
  • cosa dovrebbe succedere;
  • quale funzione deve gestirlo.

Cosa produrre

Alla fine della lezione devi avere:

  • funzione di lettura robusta minima;
  • scelta esplicita sui DTO incompleti;
  • almeno cinque casi problematici descritti;
  • eventuale normalizzazione DTO;
  • messaggio utente o nota tecnica per dati non leggibili.

Spiegazione guidata per studiare

Questa lezione va studiata su due piani. Il primo è il comportamento visibile del Registro del laboratorio: che cosa vede o fa l’utente quando registra uno strumento, cerca un dispositivo, apre un prestito o segnala un guasto. Il secondo è il confine architetturale: dove deve stare il codice che rende possibile quel comportamento.

Per gestire dati mancanti, vecchi o corrotti, il punto centrale è questo: L’infrastruttura è il bordo tecnico: salva, legge, chiama API, usa localStorage o file JSON. È importante, ma deve restare sostituibile.

Il rischio tipico è far entrare il formato salvato dentro il dominio. Un oggetto comodo per localStorage non è automaticamente il modello con cui ragiona il progetto. Per evitarlo, non partire dal file che hai già aperto nell’editor. Parti dalla domanda: “quale responsabilità sto modificando?”. Se la risposta riguarda una regola del laboratorio, guarda il dominio. Se riguarda una sequenza di operazioni, guarda i casi d’uso. Se riguarda salvataggio, file, localStorage, API o database, guarda l’infrastruttura. Se riguarda input, pulsanti, form e messaggi, guarda la Presentation.

Il tempo è sufficiente per alternare spiegazione, modifica guidata e revisione. Alla fine della lezione lo studente non deve ricordare una definizione a memoria: deve saper indicare un punto del progetto, spiegare perché quel codice sta lì e mostrare una verifica del comportamento.

Passo per passo nel progetto

  1. Rileggi il titolo della lezione e riscrivilo come domanda pratica. Per esempio: “dove deve stare questa regola?”, “chi deve salvare questo dato?”, “come verifico questo errore?”.
  2. Apri solo i file necessari. Se devi toccare più di tre file, fermati e scrivi prima una mini-mappa.
  3. Distingui modello di dominio e formato salvato.
  4. Crea una funzione di mapping leggibile.
  5. Gestisci dati mancanti o non validi.
  6. Verifica che i casi d’uso non cambino quando cambi archivio.
  7. Aggiorna una nota breve nel README o negli appunti se hai cambiato un confine del progetto.

Esempio da leggere lentamente

Questo esempio serve a ragionare, non a incollare codice senza capire:

function strumentoToDTO(strumento) {
  return {
    id: strumento.id,
    name: strumento.nome,
    category: strumento.categoria,
    status: strumento.stato
  };
}

Leggilo chiedendoti che cosa cambierebbe se domani sostituissimo la pagina web con una CLI, oppure localStorage con un’API. Se l’esempio continua ad avere senso senza riscrivere tutto, il confine è probabilmente buono. Se invece un dettaglio tecnico si propaga in molti file, il progetto sta tornando fragile.

Prova di comprensione

Prima di chiudere la lezione, rispondi per iscritto a queste domande:

  • Qual è la responsabilità principale trattata in questa lezione?
  • In quale livello del progetto dovrebbe stare?
  • Quale errore faresti se cercassi la soluzione più veloce?
  • Quale piccolo test, controllo manuale o esempio dimostra che hai capito?
  • Che cosa deve restare facile da cambiare dopo questa lezione?

Una risposta accettabile non deve essere lunga. Deve però usare parole concrete del Registro: strumento, prestito, stato, archivio, caso d’uso, messaggio, test.

Controllo finale

La lezione e completata quando puoi rispondere si:

  • localStorage vuoto non rompe l’app;
  • JSON corrotto non mostra errore tecnico grezzo;
  • so cosa faccio con DTO incompleti;
  • so distinguere migrazione e regola di dominio;
  • ho scritto almeno alcuni casi problematici.

Nella prossima lezione mettiamo insieme adapter localStorage e adapter JSON.