Un'introduzione alla gestione degli errori in Sass

Indipendentemente dalla lingua, gli errori dovrebbero essere gestiti in modo semplice e pulito, a vantaggio dell'utente finale o del prossimo sviluppatore. Quando si esegue un'azione errata su un sito, non si deve solo punch con un codice di errore o un comando in errore. Dovrebbe avvisarti con un messaggio esplicativo su cosa sta succedendo.

Questo non dovrebbe essere diverso quando si codifica per altri sviluppatori. Quando costruisci una libreria, un framework o semplicemente lavori in una squadra, non sei il solo a usare il codice. Molto probabilmente, molti sviluppatori con background molto diversi potrebbero dover usare il tuo codice, e non dovrebbero aver bisogno di scavare nel profondo della fonte e le svolte della tua mente per capire cosa sta succedendo.

Questo è il motivo per cui dovresti gestire gli errori correttamente. Anche a Sass. Anche quando si compila in qualcosa di permissivo come i CSS. Ogni volta che crei una funzione personalizzata o un mixin, devi sempre assicurarti che tutto funzioni come previsto e, in caso contrario, dovresti intraprendere un percorso diverso. 

Non so per te, ma non mi piace lasciare che il compilatore Sass fallisca. Preferirei un piccolo messaggio interessante che mi spiegasse che ho dimenticato un argomento piuttosto che affrontarlo:

Per farla breve: gestisci correttamente gli errori. Ti mostrerò come.

Cosa controllare?

Assicurandosi che tutti gli argomenti siano specificati

Una delle prime cose da fare quando si costruisce una funzione è assicurarsi che tutti gli argomenti siano specificati. Sfortunatamente Sass non inserirà nemmeno la funzione se il numero di argomenti passati non è corretto. Fortunatamente, il compilatore lo gestisce in un modo carino con un messaggio come: Mixin my-awesome-mixin manca argomento $ the-awesome-argument. quindi non è così male.

Se non vuoi lasciare questo nelle mani del compilatore e preferisci occupartene da solo, puoi aggirare il problema specificando i parametri predefiniti per tutti gli argomenti della funzione / mixin. Non solo è meglio per l'utente finale non dover specificare tutti argomenti ogni singola volta, ma consente anche di attivare la funzione / mixin in tutti i casi e di fare tutto il necessario.

Fare in modo che gli argomenti siano validi

La cosa più importante ora è assicurarsi che tutti gli argomenti siano validi. Ad esempio, se hai bisogno di un colore devi assicurarti che lo sviluppatore stia effettivamente passando un colore alla funzione e non un numero o una stringa. Se hai bisogno di un elenco di tre valori, dovresti controllare la lunghezza per assicurarti che ci sia siamo tre valori, non due o quattro. 

Fortunatamente, Sass rende molto facile farlo con un sacco di funzioni predefinite, tra cui tipo di() per verificare il tipo di dati di un valore. Tra l'altro, Sass 3.4 dovrebbe anche introdurre is-type-of (valore $, tipo $) aggirare la questione del tipo di test di () che ritorna sempre elenco mentre può essere una mappa pure.

Ad ogni modo, anche scrivendo un pezzo di codice per sviluppatori con una buona conoscenza di Sass, dovresti prestare attenzione all'input delle tue funzioni. 

Ad esempio, quando lo fai $ valore: $ input + "px", in pratica stai lanciando un numero (se $ input è un numero, ovviamente) di una stringa. Quindi se provi a farlo $ valore * 2, Sass genererà un errore perché stai tentando di moltiplicare una stringa. Maggiori informazioni su questo fenomeno in questo articolo.

... in una funzione

Affrontare gli errori in caso di una funzione personalizzata è in realtà abbastanza semplice: si controlla per qualunque cosa si debba verificare. Se la condizione non corrisponde, si ritorna falso (o nullo, vedi sotto) e avvisa l'utente con l'aiuto di @avvisare Direttiva Sass.

@function add-10 ($ number) @if type-of ($ number)! = "number" @warn "'# $ number' non è un numero di 'add-10'."; @return false;  @return $ number + 10; 

In questo caso (abbastanza sciocco sono d'accordo), se il numero di $ argomento non è un numero, la funzione restituirà falso e l'utente verrà avvisato di aver passato un argomento errato da un messaggio che appare nel loro terminale: 'SWAG' non è un numero per 'add-10'.

Se l'argomento è valido, restituisce semplicemente il numero + 10. Semplice come una torta.

... in un mixin

Quando si tratta di un mixin, è leggermente più complicato perché in realtà non si restituisce qualcosa; invece tu scarichi le regole CSS. Per aggirare il problema, è necessario dichiarare un booleano che funge da verificatore di validità. Si prega di considerare il seguente esempio:

@mixin module ($ name) // Inizializza un controllo di validità booleano $ everything-okay: true; // Verifica validità argomento @if tipo-of ($ nome)! = "Stringa" @warn "'# $ nome' non è una stringa per 'modulo'."; $ tutto-okay: falso;  // Se tutto è ancora a posto, dump mixin content @if $ everything-okay @content; 

Una parola sull'elenco

Quando vuoi assicurarti che uno degli argomenti sia un elenco con più elementi al suo interno, devi sempre testare la lunghezza piuttosto che il tipo di dati. Per dirla semplicemente, Sass tratta tutti i valori come elenchi di elementi singoli, e in alcuni casi puoi trovarti con un elenco di singoli elementi che in realtà è ancora un elenco.

D'altra parte, un potenziale problema quando si controlla il lunghezza è che può essere un carta geografica anche. Un modo per essere assolutamente sicuri di trovarti di fronte a un elenco di più valori è farlo in questo modo:

@if length ($ value)> 1 e type-of ($ value)! = map // È un elenco di più valori

Quando sta controllando troppo il controllo?

Se sono completamente onesto con te, direi mai. Non si può mai essere troppo prudenti e probabilmente è possibile verificare qualsiasi argomento di qualsiasi funzione e qualsiasi mixin della propria applicazione. Tuttavia, probabilmente non è necessario. Ho una regola d'oro quando si tratta di controllo degli argomenti: se è probabile che il valore causi il crash del compilatore Sass, allora dovresti controllarlo

Ciò significa che se hai un mixin che accetta argomenti che sono direttamente usati come valori per le proprietà CSS, non penso che abbia senso controllarli in modo aggressivo. Lo scenario peggiore è che tali valori verranno scaricati nell'output CSS, con conseguente CSS non valido che non verrà compreso dal browser. A parte un paio di byte extra caricati, non ci saranno molti danni.

Ad esempio, considera il seguente mixin:

@mixin size ($ width, $ height: $ width) width: $ width; altezza: $ altezza; 

E ora considera il seguente utilizzo:

.element @include size (10, "string"); 

Il CSS risultante sarà:

.element width: 10; altezza: "stringa"; 

Qualsiasi browser rifiuterà semplicemente entrambe le proprietà perché i loro valori non sono validi. Nessun grosso problema.

Gestione degli errori nelle funzioni profondamente annidate

Con quello che abbiamo appena visto, dovresti essere in grado di gestire correttamente il 99% dei possibili errori, comunque lì è un caso in cui è sempre più difficile stare al passo con Sass: quando si tratta di errori da una funzione chiamata da una funzione chiamata da una funzione ...

Ho affrontato questa cosa quando scrivevo SassyJSON, un parser JSON scritto in Sass. Fondamentalmente si passa una stringa JSON al JSON-decodifica funzione, che la trasmette al  _json-decodifica - Valore funzione, che quindi la trasmette a _json-decodifica - * funzione in base al tipo di valore che viene analizzato. Ad ogni modo, non era insolito per me avere tre, quattro, forse cinque chiamate di funzioni annidate l'una nell'altra.

Sfortunatamente, in tal caso, non esiste un modo pulito per fermare l'esecuzione. Devi fare in modo che i tuoi errori diventino il massimo fino al livello superiore controllando manualmente il ritorno della funzione ad ogni livello. Ad esempio, se si ha un errore nella funzione più profonda, dovrebbe restituire false alla funzione chiamante, che dovrebbe quindi controllare questo valore, rendersi conto che è falso, quindi restituisci false alla funzione superiore, e così via fino a raggiungere quella più alta che poi interrompe l'esecuzione.

È piuttosto difficile da affrontare, ma non c'è scelta. Detto questo, se devi annidare diversi livelli di funzioni, direi che non stai usando Sass in modo corretto.

Cosa restituire in caso di errore

Ogni volta che qualcosa va storto, puoi restituire vari valori, falso e nullo essendo i più popolari. Suppongo che potresti tornare -1 o vuoto 0 se vieni da uno sfondo JavaScript. Immagino che potresti anche restituire qualcosa del genere CODICE DI ERRORE anche se ciò renderebbe il controllo di un errore un po 'più complicato.

Io uso per tornare falso perché quello parla da solo: è falso. Tuttavia questo potrebbe essere un problema con le funzioni che dovrebbero restituire un booleano. Come faresti a sapere se la funzione ritorna falso perché il risultato è stato valutato falso, o falso perché c'è stato un errore?

Pertanto, puoi decidere di scegliere un altro valore. C'è una cosa interessante con nullo: una proprietà CSS con un valore di nullo non sarà compilato alla fonte. Fondamentalmente ciò significa che se si utilizza una funzione Sass come valore per una proprietà CSS e qualcosa non va, la proprietà CSS verrà semplicemente omessa dal compilatore Sass.

Penso che sia davvero carino per qualcosa del genere:

.element background: get-color-from-theme ('admin'); 

Se la funzione get-colore-da-tema è stato ben progettato, dovrebbe assicurarsi che il Admin il tema esiste ed è effettivamente associato a un valore di colore. Se Admin non esiste, quindi la funzione ritornerebbe nullo quale risulterebbe in sfondo: null. Ciò renderà Sass omettere la regola durante la compilazione del file in CSS.

In bisogno di a gettare() Funzione

La maggior parte delle lingue ha un gettare funzione o direttiva. Solitamente, questa funzione accetta un messaggio di errore o un'eccezione come argomento e interrompe semplicemente l'esecuzione dello script per visualizzare questo messaggio (nella console o qualcosa del genere) ogni volta che si verifica un errore. Ad esempio in JavaScript, puoi fare qualcosa del genere:

if (typeof myVariable === "undefined") throw new UserException ("'myVariable' dovrebbe essere definito");  

Sfortunatamente, Sass non ha questo. Fondamentalmente in Sass non è assolutamente possibile interrompere una funzione o un mixin dall'esecuzione. Potresti crearne uno, ma in pratica non fermerebbe la funzione, restituirebbe semplicemente false e registrerebbe un messaggio.

@function throw ($ log) @warn $ log; @return false; 

Invece di scrivere manualmente il @avvisare direttiva e il @return false ogni volta, puoi usare il gettare() la funzione, tuttavia, ricorda che non fa alcuna magia né ferma la riproduzione dello script. Restituisce semplicemente 'false' e registra un messaggio di errore.

Detto questo, avendo un gettare la direttiva è stata rivolta diverse volte ai manutentori di Sass e sembra che abbiano concordato che non sarebbe stato così male implementare un sistema @errore direttiva che interromperebbe l'attuale esecuzione dell'ambito in base al numero 747. Forse per il 3,4, non ne sono sicuro.

Pensieri finali

Non importa come lo fai, dovresti sempre controllare la funzione e mixare gli input piuttosto che lasciare che il compilatore si arresti in modo anomalo perché incontra qualcosa di inaspettato. Come sviluppatore preferirei avere un registro pulito e niente output piuttosto che una traccia di stack enorme, ma ancora una volta non sono io.

Come esempio dal vivo, ti suggerisco di dare un'occhiata ad una piccola libreria di pulsanti che ho costruito qualche tempo fa. La maggior parte del codice dal core mixin è il controllo degli argomenti e la gestione degli errori. Rende il mixin aspetto affollato, ma penso che sia essenziale per gli sviluppatori che useranno il codice.

Alla fine, assicurati solo di trovare qualcosa che sia adatto a te e alla tua squadra e starai bene.