Un server dovrebbe essere "clemente" in ciò che accetta e "scartare input errati in modo silenzioso"?

27

Avevo l'impressione che ormai tutti concordassero che questa massima era un errore. Ma di recente ho visto questa risposta che ha un commento "essere indulgente" di 137 volte in più (ad oggi).

Secondo me, la clemenza in ciò che i browser accettano è stata la causa diretta del disordine totale che l'HTML e alcuni altri standard web erano di qualche anno fa, e solo recentemente ha iniziato a cristallizzarsi correttamente da quel pasticcio. Il modo in cui lo vedo, essere indulgente in ciò che accetti porterà a questo.

La seconda parte della massima è "scartare input errato in modo silenzioso, senza restituire un messaggio di errore a meno che ciò non sia richiesto dalla specifica" , e questo sembra offensivo borderline. Qualsiasi programmatore che ha sbattuto la testa contro il muro quando qualcosa fallisce silenziosamente saprà cosa intendo.

Quindi, ho completamente torto su questo? Il mio programma dovrebbe essere clemente in ciò che accetta e ingoiare silenziosamente gli errori? O sto interpretando male ciò che questo dovrebbe significare?

La domanda originale diceva "programma" e prendo spunto da tutti su questo punto. Può essere sensato che i programmi siano clementi. Ciò che intendevo veramente, tuttavia, sono le API: interfacce esposte a altri programmi , piuttosto che persone. HTTP è un esempio. Il protocollo è un'interfaccia utilizzata solo da altri programmi. Le persone non forniscono mai direttamente le date che vanno in intestazioni come "If-Modified-Since".

Quindi, la domanda è: il server che implementa uno standard dovrebbe essere clemente e consentire date in diversi altri formati, oltre a quello effettivamente richiesto dallo standard? Credo che il "essere indulgente" dovrebbe applicarsi a questa situazione, piuttosto che alle interfacce umane.

Se il server è clemente, potrebbe sembrare un miglioramento generale, ma penso che in pratica porti solo a implementazioni client che finiscono per affidarsi alla clemenza e quindi a non funzionare con un altro server questo è clemente in modi leggermente diversi.

Quindi, un server che espone alcune API dovrebbe essere clemente o è una pessima idea?

Ora sulla gestione indulgente dell'input dell'utente. Considera YouTrack (un software di tracciamento dei bug). Usa una lingua per l'immissione di testo che ricorda Markdown. Tranne che è "indulgente". Ad esempio, scrivendo

- foo
- bar
- baz

è non un modo documentato di creare un elenco puntato, eppure ha funzionato. Di conseguenza, è finito per essere usato molto durante il nostro bugtracker interno. La versione successiva viene fuori, e questa caratteristica clemente inizia a funzionare in modo leggermente diverso, rompendo un sacco di liste che (male) hanno usato questa (non) funzionalità. Il modo documentato per creare elenchi puntati funziona ancora, naturalmente.

Quindi, il mio software dovrebbe essere clemente in ciò che input utente accetta?

    
posta Roman Starkov 12.06.2012 - 15:20
fonte

11 risposte

8

Naturalmente hai perfettamente ragione. I programmi non dovrebbero mai essere "indulgenti", poiché così facendo serve solo a mascherare i problemi. I problemi dovrebbero essere evidenziati, non spazzati sotto il tappeto. Un messaggio di errore informativo è assolutamente necessario affinché un programma sia utile per l'utente.

La maggior parte delle volte che vengono forniti dati errati / non validi, il fornitore di quei dati (sia che si tratti di un utente o l'output di qualche altro programma) probabilmente non sapeva che non era valido. Ingoiare l'errore li terrà nella convinzione che sia (o potrebbe essere) valido, il che prolifera i dati non validi.

L'unico modo per i sistemi di interoperare è che tale interoperabilità sia definita in modo completo e non ambiguo. Un programma che accetta dati al di fuori delle specifiche rende accettabili i dati di fatto anche se non sono validi dalla specifica, il che non solo rende più difficile la compatibilità di un carico enorme, ma significa anche che non è più definito formalmente. Il programma stesso è ora lo standard de facto . Pertanto, i programmi clementi sono impossibili da sviluppare ulteriormente o da sostituire perché non è possibile apportare modifiche minime al modo in cui opera.

    
risposta data 12.06.2012 - 15:56
fonte
25

Penso che tutto dipenda da chi è il tuo target demografico. Se sono programmatori, allora assolutamente no. Il tuo programma dovrebbe fallire duro e urlare un sanguinoso omicidio. Tuttavia, se il tuo pubblico target non è programmatori, allora il tuo programma dovrebbe essere clemente dove può gestire le eccezioni con garbo, altrimenti, sussurrare un dolce sanguinoso omicidio.

Come caso di studio, prendi il lettore Flash NPAPI. Esiste una versione di "rilascio" per coloro a cui non interessa il 99% degli errori che possono verificarsi, ma esiste anche una versione di "debug" che può essere utilizzata per gridare un sanguinoso omicidio quando qualcosa va storto. Ogni supporto riproduce il contenuto Flash ovviamente, ma è mirato a due dati demografici completamente diversi.

Alla fine, penso che la cosa importante sia: a cosa interessano i tuoi utenti?

    
risposta data 12.06.2012 - 16:03
fonte
6

Fallire silenziosamente è la cosa peggiore che potresti mai fare, mai. Hai provato a eseguire il debug di un'API con errore non presidiato? È impossibile .

C'è "Fai del tuo meglio per recuperare ma invia un errore dettagliato" e c'è "Silent failure".

    
risposta data 12.06.2012 - 17:03
fonte
6

Esistono due tipi di "lenient": uno è quello di accettare input non corretti e cercare di dare un senso a questo, e l'altro è accettare diversi tipi di input.

In generale, vuoi sempre il secondo quando è fattibile. Il primo è quando muori velocemente e duramente. Un esempio: Date.

Ecco alcuni esempi di input, tra cui valido, non valido e ambiguo.

  • 2011-01-02
  • 01/02/2011
  • Jan 2, 2011
  • 2-Jan-2011
  • Green

C'è solo un input non valido qui: Green . Non provare nemmeno ad accettarlo come una data. Poiché Green non è ovviamente una data, questo è un caso in cui il mancato funzionamento silenzioso è accettabile.

01/02/2011 è valido, ma ambiguo. Non devi necessariamente sapere se è stato inserito o meno come data USA (2 gennaio) o meno (1 febbraio). Qui, probabilmente è meglio fallire rumorosamente e chiedere all'utente una data univoca.

2011-01-02 è di solito considerato non ambiguo, quindi è spesso bene andare avanti e assumere che sia il formato "AAAA-MM-GG", e fallire solo in seguito. È un po 'una scelta di giudizio, però, quando si tratta di input dell'utente.

Jan 2, 2011 e 2-Jan-2011 sono validi e non ambigui, devono essere accettati. Tuttavia, The Second of January of the year 2011 è anche valido e non ambiguo, ma andare così lontano a fini di clemenza è eccessivo. Vai avanti e fallo silenziosamente, proprio come Green .

In breve , la risposta è "dipende". Dai un'occhiata a ciò che può essere immesso e assicurati di non accettare mai tipi di input in conflitto (come DD/MM/YYYY vs MM/DD/YYYY ).

Nel contesto della domanda / commento collegato , questo è un caso di 2011-01-02 . L'input è simile a JSON e verrà convalidato come JSON anche se il mimetype è sbagliato; vai avanti e prova ad usarlo anche se fallisce ad un certo punto più avanti sulla linea.

    
risposta data 12.06.2012 - 20:13
fonte
3

Mi sembra che la legge di Postel - "Sii prudente in ciò che fai, sii liberale in ciò che accetti agli altri" è ciò che viene discusso per un servizio JSON. Questo di solito è applicato ai servizi web e non all'interfaccia utente.

Per l'utente un feedback costruttivo degli utenti e l'ingresso dell'utente contro la contraffazione è la regola empirica che usiamo.

    
risposta data 12.06.2012 - 16:36
fonte
3

Penso che questo sia ben trattato in capitolo 1, sezione 6 di TAOUP. In particolare, la regola di riparazione , che stabilisce che un programma dovrebbe fare ciò che può con un input, inoltrare i dati corretti in avanti e, se la risposta corretta è fallita, farlo al più presto.

Un concetto simile è programmazione difensiva . non sai quale tipo di input riceverai, ma il tuo programma dovrebbe essere abbastanza robusto da coprire i casi tutti . Ciò significa che dovrebbe essere programmato in casi di recupero per problemi noti come input maciullati, e un catch all case per gestire le incognite.

Quindi scartare input errati in modo silenzioso va bene, fintanto che sta gestendo quell'input. Non dovresti mai lasciarlo cadere sul pavimento, per così dire.

Per un'API, penso che essere indulgente sia lo stesso di un programma. L'input è ancora sbagliato , ma stai tentando di riparare il più possibile. La differenza è ciò che è considerato valido repair . Come fai notare, un'API clemente può causare problemi poiché le persone usano "funzionalità" che non esistono.

Ovviamente, un'API è solo una versione di livello inferiore della regola di composizione . In quanto tale, è realmente coperto dalla regola della sorpresa minima , poiché è un'interfaccia

Come fa notare la citazione di Spencer, evitate la somiglianza superficiale, che può essere discusso sugli input "fuzzy". In queste condizioni, direi che tutto fa pensare al programma che non può riparare, perché non saprà cosa si desidera, ed è meno sorprendente per la base utente.

Tuttavia, hai a che fare con date che hanno molti "standard". A volte anche questi si mischiano in un singolo programma (catena). Dal momento che sai che è prevista una data, il tentativo di riconoscere la data è solo un buon design. Soprattutto se la data proviene da un programma esterno e viene passata senza modifiche per un secondo sulla strada da percorrere.

    
risposta data 12.06.2012 - 17:07
fonte
2

I programmi distribuiti sul server, la maggior parte delle volte, richiedono migliaia di richieste ogni minuto o ogni secondo. Se un programma server accetta e corregge input errati dai client, temo che abbia 2 svantaggi:

  1. Perdita di tempo prezioso del server. Con oltre 1000 richieste al secondo, il controllo degli errori in ogni richiesta può riflettere una risposta lenta per ciascun client.
  2. Ingiusto verso i programmi client / client che forniscono input corretti. Oltre a ciò, quando un programmatore lato server si trova sul codice server, deve pensare ai vari casi di quali input difettosi possono essere. Chi lo deciderà?

I programmi server non dovrebbero accettare input errati, ma i server dovrebbero restituire un messaggio di errore al client, se c'è un input errato.

    
risposta data 14.06.2012 - 12:09
fonte
2

Il comportamento ideale, concettualmente, è fare ciò che può essere fatto in sicurezza, assicurando allo stesso tempo che qualcuno che può risolvere qualsiasi problema sia in qualche modo informato su di loro. In pratica, ovviamente, l'ultimo vincolo è spesso impossibile da soddisfare direttamente, e quindi la domanda diventa la cosa migliore per gestire gli input dubbi.

Una cosa che può essere molto utile nella progettazione di un protocollo, delle specifiche di formattazione o "linguaggio" è di avere un mezzo per distinguere quattro categorie di potenziali elementi non compresi:

  1. Cose che dovrebbero essere filtrate se non capite.
  2. Cose che dovrebbero essere ignorate se non capite, ma comunque mantenute se i dati devono essere trasmessi (magari in una sorta di wrapper per indicare che ha attraversato almeno una fase che non l'ha capita)
  3. Cose che dovrebbero generare un avviso se non capite, ma non dovrebbero impedire un tentativo di recupero dei dati (ad esempio all'interno di una pagina web, un oggetto il cui tipo è sconosciuto, ma il cui fine all'interno del file è ben definito, potrebbe essere reso come una "X" rossa senza impedire il rendering del resto della pagina.)
  4. Cose che indicherebbero che qualsiasi cosa che non può capirle è suscettibile di avere problemi gravi e irrecuperabili altrove (ad es. un indicatore che i dati rimanenti sono compressi e che qualsiasi cosa possa essere compresa da qualsiasi cosa che possa eseguire la decompressione richiesta) .

Avere una convenzione ben definita con la quale le app in grado di leggere qualsiasi versione di un formato di dati saranno in grado di riconoscere quale categoria è appropriata per qualsiasi cosa generata in conformità con le versioni successive è un approccio molto migliore rispetto al tentativo di misure di compatibilità ad hoc più avanti. Ad esempio, se un formato di file ha delle righe nella forma "Tag: Valore", si potrebbe specificare che il primo carattere di qualsiasi tag indicherà la categoria a cui appartiene; per i tag delle categorie silent-ignore, si potrebbe avere il primo carattere che indica anche la versione dello standard per cui il tag dovrebbe essere valido (in modo che se un tag "silent-ignore" afferma di essere presente nella versione 3 di lo standard, un parser per la versione lo ignorerebbe silenziosamente, ma un parser per la versione 3 o successiva emetterebbe squawk se non fosse in grado di analizzarlo).

In ogni caso, la cosa più importante è evitare di convertire dati ambigui o fraintesi in dati errati. In alcuni casi, potrebbe essere preferibile rifiutarsi di propagare dati ambigui, anche se in altri casi potrebbe essere meglio propagarlo esattamente come ricevuto nel caso in cui il destinatario lo considerasse non ambiguo. Ciò che è veramente pericoloso se non addirittura dannoso è la conversione dei dati usando ipotesi diverse, ad es. convertire un elenco di date come:

01/12/12
13/12/12
99/12/12

in un elenco di date come

2012-01-12
2012-12-13
1999-12-12

Anche se uno ha una lista con alcune date erroneamente inserite, potrebbe essere possibile per un essere umano fornire una lista nel formato originale per determinare quale formato era corretto, e contrassegnare i valori dubbi per ulteriori ricerche (verificando contro altri record , ecc.) Il rendering delle date in quest'ultimo formato, tuttavia, li aggirerebbe irrimediabilmente e irrimediabilmente.

    
risposta data 10.07.2012 - 20:51
fonte
1

La mia esperienza di interfaccia utente deriva principalmente dai sistemi desktop. I siti Web sono diversi, anche se ho visto alcuni siti che potrebbero sfidare un sistema desktop. Ma per quello che vale:

Ho trovato che i messaggi di errore dovrebbero essere l'ultima risorsa; un sistema ideale non li avrebbe affatto. La cosa migliore da fare non è consentire le voci errate in primo luogo: l'utente non può entrare in "verde" se sta selezionando da un elenco a discesa di mesi. Non può premere un pulsante in grigio.

La prossima cosa migliore da fare è accettare i dati non validi. Supponi di visualizzare un istogramma delle vendite giornaliere per un mese. Dopo l'input dell'utente, il grafico copre un secolo e la barra un secolo fuori è 10 volte superiore rispetto agli altri. L'utente ora sa di aver fatto qualcosa di sbagliato e, inoltre, sa molto più su ciò che ha fatto di sbagliato rispetto a qualsiasi messaggio possa dirgli. Quando la voce è grafica, trascinando un mouse, ad esempio, questo tipo di feedback funziona ancora ed è inestimabile. Un gruppo di input può non essere valido, ma con questo metodo l'utente ottiene un riscontro immediato e dettagliato sui risultati di ogni posizione del mouse.

Tutto ciò che ho detto, a volte l'utente deve sapere perché il pulsante è disattivato in modo che non possa spingerlo. Quindi non c'è alcun aiuto (se c'è è , fammi sapere) ma per annullare il pulsante e, quando fa clic su di esso, dargli una buona spiegazione del motivo per cui il pulsante non funziona momento.

    
risposta data 13.06.2012 - 17:36
fonte
0

L'affermazione riguarda l'invio di informazioni su Internet. Una delle cose con l'invio di informazioni su Internet è che non sempre raggiungerà il bersaglio o sarà frammentato.

    
risposta data 12.06.2012 - 16:46
fonte
0

Qualcosa che sembra mancare qui - quali sono le conseguenze del fallimento?

Visualizza una pagina Web? Dovresti fare tutto il possibile per tollerare input sbagliati. Le tue scelte sono di mostrare ciò che puoi o lanciare un errore. L'ultimo corso non fornisce all'utente nulla e quindi dovrebbe essere solo l'ultima risorsa in quanto fornisce all'utente un risultato completamente inutile, sarebbe piuttosto difficile per un errore essere peggio di questo.

D'altra parte, se sta chiedendo il bersaglio di un Minuteman III, rifiuti "Mosca" come input poiché è potenzialmente ambiguo.

    
risposta data 11.07.2012 - 02:05
fonte

Leggi altre domande sui tag