modulo 12 di 24 / Ore 21-40

Moduli 9-16 / Checkpoint 40 ore

Errore di input: dati mancanti o non validi

Riconoscere e gestire gli errori di input nel Registro: dati mancanti, vuoti o malformati che arrivano dall'utente prima ancora di raggiungere il dominio.

25 minArchitettura del software

Errore di input: dati mancanti o non validi

Questa lezione appartiene al Modulo 12 — Errori, validazione e messaggi.

Cos’è un errore di input

Un errore di input nasce prima che i dati raggiungano il dominio. L’utente ha inviato dati mancanti, vuoti o in formato sbagliato — e il sistema deve accorgersene il prima possibile.

Esempi nel Registro del laboratorio:

  • il campo “nome strumento” è vuoto
  • la categoria non è stata selezionata
  • l’ID strumento non è stato fornito nel comando
  • il nome è troppo corto (meno di 2 caratteri) o troppo lungo (più di 80)

Questi non sono violazioni di regole del laboratorio — sono dati che non hanno nemmeno la forma giusta per essere elaborati.

Dove validare l’input

L’input viene validato in due posti con scopi diversi:

Presentation (UI)   →  feedback immediato all'utente (campo rosso, messaggio inline)
Application         →  controllo difensivo prima di passare al dominio

La UI valida per comodità — mostrare errori prima del submit. Ma non basta: se qualcuno bypassa la UI (chiamata diretta all’API, script), i dati arrivano ugualmente al caso d’uso.

Il caso d’uso valida per sicurezza — verifica che i dati abbiano la forma minima richiesta prima di usarli.

Il dominio non valida input: presuppone che i dati che riceve siano già stati controllati.

Esempi concreti nel Registro

// Validazione nell'Application (caso d'uso o funzione separata)
function validaComandoRegistraStrumento(comando) {
  const errori = [];

  if (!comando.nome || comando.nome.trim().length < 2) {
    errori.push("NOME_MANCANTE_O_TROPPO_CORTO");
  }
  if (comando.nome && comando.nome.trim().length > 80) {
    errori.push("NOME_TROPPO_LUNGO");
  }
  if (!comando.categoria) {
    errori.push("CATEGORIA_MANCANTE");
  }

  if (errori.length > 0) throw new Error(errori[0]);
}
// Validazione nella UI (feedback immediato)
function validaFormStrumento(form) {
  const nome = form.nome.value.trim();
  if (nome.length < 2) {
    mostraErroreCampo("nome", "Il nome deve avere almeno 2 caratteri.");
    return false;
  }
  return true;
}

Gestire più errori contemporaneamente

Un form con più campi può avere più errori insieme. Raccoglierli tutti è più utile che fermarsi al primo:

function validaComandoRegistraStrumento(comando) {
  const errori = [];

  if (!comando.nome || comando.nome.trim().length < 2) errori.push("NOME_NON_VALIDO");
  if (!comando.categoria) errori.push("CATEGORIA_MANCANTE");
  if (!comando.id) errori.push("ID_MANCANTE");

  if (errori.length > 0) throw new Error(errori[0]);
}

Per i principianti, lanciare il primo errore è sufficiente. In sistemi più grandi si usa un oggetto errore con tutti i problemi.

Come si distingue dall’errore di dominio

Errore di input Errore di dominio
Nome vuoto Strumento guasto
ID non fornito Prestito già chiuso
Categoria non selezionata Strumento già in prestito
Formato non valido Stato non ammesso

La regola pratica: l’errore di input si risolve correggendo ciò che si è scritto. L’errore di dominio si risolve cambiando la situazione del laboratorio.

Come mostrare i messaggi

// Presentation
async function gestisciSubmitForm(evento) {
  evento.preventDefault();

  const comando = {
    nome: document.getElementById("nome").value,
    categoria: document.getElementById("categoria").value
  };

  try {
    validaComandoRegistraStrumento(comando); // ← errori di input
    await registraStrumento(comando);        // ← errori di dominio / applicativi
    mostraSuccesso("Strumento registrato.");
  } catch (errore) {
    const messaggi = {
      NOME_NON_VALIDO: "Il nome deve avere almeno 2 caratteri.",
      CATEGORIA_MANCANTE: "Seleziona una categoria.",
      ID_MANCANTE: "ID strumento mancante."
    };
    mostraMessaggio(messaggi[errore.message] ?? "Dati non validi. Controlla i campi.");
  }
}

Procedura guidata

  1. Apri il form di registrazione strumento nel tuo progetto.
  2. Elenca i campi obbligatori e i loro vincoli (lunghezza minima, formato).
  3. Aggiungi la funzione validaComandoRegistraStrumento se non esiste.
  4. Verifica che il caso d’uso chiami la validazione prima di usare i dati.
  5. Assicurati che la UI mostri messaggi chiari per ogni errore.

Attività in classe

## Errori di input nel mio Registro

Form o operazione analizzata:

Campi obbligatori e vincoli:

Funzione di validazione esistente (o da creare):

Codici errore usati:

Messaggi utente corrispondenti:

Test o verifica manuale:

Spiegazione guidata per studiare

Gli errori di input sono i più comuni e i più semplici da gestire — ma anche i più facili da ignorare. Un progetto che non valida l’input può finire con dati vuoti, numeri al posto di testi, o oggetti incompleti che causano errori misteriosi più in profondità nel sistema.

Il punto centrale è: valida l’input il più presto possibile, prima che raggiunga il dominio. Il dominio lavora meglio se può assumere che i dati che riceve siano già validi nella forma.

La validazione ha due livelli: la UI (per comodità, feedback immediato) e il caso d’uso (per sicurezza, controllo definitivo). Entrambi sono necessari — uno non sostituisce l’altro.

Passo per passo nel progetto

  1. Cerca tutti i punti in cui il progetto legge dati dal DOM (document.getElementById, e.target.value).
  2. Per ogni lettura: il valore viene usato direttamente o viene validato prima?
  3. Aggiungi validazione dove manca: almeno il controllo “non è vuoto”.
  4. Verifica che i codici errore siano specifici (NOME_NON_VALIDO, non ERRORE).
  5. La UI mostra messaggi vicino al campo sbagliato?

Esempio da leggere lentamente

// Tre livelli di controllo sull'input del nome

// 1. Nel DOM (non affidabile da solo)
const nome = document.getElementById("nome").value;

// 2. Nella validazione del comando (Application)
if (!nome || nome.trim().length < 2) throw new Error("NOME_NON_VALIDO");

// 3. Nel dominio (presuppone già validato — non dovrebbe mai ricevere stringa vuota)
function creaStrumento({ id, nome, categoria }) {
  return { id, nome: nome.trim(), categoria, stato: "disponibile" };
}

Ogni livello ha il suo scopo. Non basta uno solo.

Prova di comprensione

  • Cosa succede se non si valida l’input e si passa una stringa vuota al dominio?
  • Perché la validazione nella UI non è sufficiente da sola?
  • Come si distingue un errore di input da un errore di dominio? Fai un esempio.

Errori da evitare

  • usare i dati dell’utente senza nessun controllo prima di passarli al dominio;
  • fare la validazione solo nella UI e non nel caso d’uso;
  • usare un codice errore generico (ERRORE_FORM) invece di specifici per campo;
  • mostrare errori tecnici all’utente quando l’input è mancante (es. Cannot read property 'trim' of undefined).

Prodotto da consegnare

Può essere:

  • una funzione validaComandoRegistraStrumento con almeno tre controlli;
  • un test che verifica che la funzione di validazione lanci l’errore corretto per input mancante;
  • una lista di tutti i campi obbligatori del Registro con i rispettivi vincoli nel README.

Checklist di chiusura

  • Ogni form ha una funzione di validazione
  • La validazione viene chiamata nel caso d’uso prima di usare i dati
  • I codici errore sono specifici per campo
  • La UI mostra messaggi comprensibili per ogni errore di input
  • C’è almeno un test sulla funzione di validazione

Domande per la revisione

  • Hai trovato campi che vengono letti senza nessun controllo?
  • I tuoi messaggi di errore dicono all’utente cosa deve correggere?
  • Un test che passa un oggetto vuoto al caso d’uso — cosa succede?

Risultato atteso

Alla fine lo studente deve saper dire:

Nel mio Registro, i campi obbligatori per [operazione] sono: [lista].
La validazione avviene in [funzione/file].
I codici errore sono: [lista].
Ho verificato con [test / scenario manuale] che la validazione funziona.

Se questa spiegazione non è possibile, la lezione non è ancora davvero conclusa.