Een inleiding tot foutafhandeling in Sass

Wat de taal ook is, fouten moeten op een eenvoudige en eenvoudige manier worden afgehandeld, of dat nu in het voordeel is van de eindgebruiker of de volgende ontwikkelaar. Wanneer u een onjuiste actie uitvoert op een site, moet deze niet alleen een foutcode of een falende opdracht bevatten. Het zou je moeten waarschuwen met een verklarende boodschap over wat er aan de hand is.

Dit zou niet anders mogen zijn bij het coderen voor andere ontwikkelaars. Wanneer u een bibliotheek, een framework of gewoon in een team samenstelt, bent u niet de enige die de code gebruikt. Het is heel goed mogelijk dat veel ontwikkelaars met zeer verschillende achtergronden uw code moeten gebruiken en dat ze niet diep in de bron en de wendingen van uw geest moeten graven om erachter te komen wat er aan de hand is..

Dit is de reden waarom u fouten correct moet afhandelen. Zelfs in Sass. Zelfs als het compileert met iets dat even toegeeflijk is als CSS. Wanneer u een aangepaste functie of een mixin bouwt, moet u altijd zorgen dat alles werkt zoals verwacht en wanneer dit niet het geval is, moet u een ander pad nemen. 

Ik weet het niet voor je, maar ik vind het echt niet leuk om de Sass-compiler te laten falen. Ik heb liever een leuke kleine boodschap die me uitlegt dat ik een argument ben vergeten in plaats van het hoofd te bieden aan:

Lang verhaal kort: behandel fouten correct. Ik zal je laten zien hoe.

Wat te controleren?

Ervoor zorgen dat alle argumenten zijn gespecificeerd

Een van de eerste dingen die u moet doen bij het bouwen van een functie, is controleren of alle argumenten zijn opgegeven. Helaas komt Sass niet eens in de functie als het aantal argumenten dat wordt doorgegeven onjuist is. Gelukkig verwerkt de compiler het op een mooie manier met een bericht als: Mixin my-awesome-mixin mist argument $ the-awesome-argument. dus het is niet zo erg.

Als je dit niet in de handen van de compiler wilt laten staan ​​en er liever zelfstandig mee om wilt gaan, kun je er omheen werken door standaardparameters op te geven voor alle argumenten uit de functie / mixin. Het is niet alleen beter voor de eindgebruiker om niet te specificeren allemaal argumenten elk eenmalig, maar u kunt ook in alle gevallen de mixin / functie activeren en alles doen wat u moet doen.

Het maken van goede argumenten is geldig

Het belangrijkste is nu om ervoor te zorgen dat alle argumenten geldig zijn. Als u bijvoorbeeld een kleur nodig heeft, moet u ervoor zorgen dat de ontwikkelaar een kleur aan de functie doorgeeft en niet een nummer of een tekenreeks. Als je een lijst met drie waarden nodig hebt, moet je de lengte controleren om daar zeker van te zijn zijn drie waarden, geen twee of vier. 

Gelukkig maakt Sass het heel gemakkelijk om dit te doen met een aantal standaardfuncties, waaronder soort van() om het gegevenstype van een waarde te controleren. Overigens zou Sass 3.4 zelfs moeten introduceren is-type-van ($ waarde, $ type) om het probleem van het testen van het type te omzeilen () die altijd terugkeert lijst terwijl het ook een kaart kan zijn.

Hoe dan ook, zelfs wanneer je een stuk code schrijft voor ontwikkelaars met een behoorlijke kennis van Sass, moet je aandacht besteden aan de invoer van je functies. 

Bijvoorbeeld wanneer $ waarde: $ invoer + "px", je bent in principe een nummer aan het gieten (als $ ingang is een nummer, uiteraard) aan een string. Dan als je het probeert te doen $ waarde * 2, Sass zal een fout genereren omdat u een reeks probeert te vermenigvuldigen. Meer informatie over dit fenomeen in dit artikel.

... in een functie

Omgaan met fouten in het geval van een aangepaste functie is eigenlijk vrij eenvoudig: u controleert op wat er moet worden gecontroleerd. Als de conditie niet overeenkomt, keer je terug vals (of nul, zie hieronder) en waarschuw de gebruiker met hulp van de @waarschuwen Sass-richtlijn.

@function add-10 ($ number) @if type-of ($ number)! = "number" @warn "'# $ number' is geen nummer van 'add-10'."; @return false;  @return $ nummer + 10; 

In deze (nogal gekke ik ga akkoord) geval, als de $ number argument is geen getal, de functie zal terugkeren vals en de gebruiker zal gewaarschuwd worden dat ze een verkeerd argument hebben doorgegeven door een bericht dat in hun terminal verschijnt: 'SWAG' is geen cijfer voor 'add-10'.

Als het argument geldig is, retourneert het eenvoudig het nummer + 10. Eenvoudig als taart.

... in een mixin

Als je met een mixin bezig bent, is het iets gecompliceerder omdat je niet echt iets retourneert; in plaats daarvan dump je CSS-regels. Om dit probleem te omzeilen, moet u een boolean declareren die dient als een geldigheidscontrole. Bekijk het volgende voorbeeld:

@mixin-module ($ naam) // Initialiseer een geldigheidscontrole boolean $ alles-oke: waar; // Controleer op argumentvaliditeit @if type-of ($ naam)! = "String" @warn "'# $ name' is geen tekenreeks voor 'module'."; $ alles-oké: fout;  // Als alles nog steeds in orde is, dum dan de inhoud van de mix @if $ alles-oke @content; 

Een woord over lijst

Als u wilt controleren of een van de argumenten een lijst met meerdere items is, moet u altijd de lengte testen in plaats van het gegevenstype. Om het eenvoudig te zeggen, Sass behandelt alle waarden als lijsten met één element, en in sommige gevallen kun je jezelf vinden met een lijst met één item die eigenlijk nog steeds een lijst.

Aan de andere kant, een mogelijk probleem bij het controleren van de lengte is dat het een kan zijn kaart ook. Een manier om absoluut zeker te weten dat u voor een lijst met meerdere waarden staat, is door het als volgt te doen:

@if length ($ value)> 1 en type-of ($ value)! = map // Het is een lijst met meerdere waarden

Wanneer is het controleren van te veel controleren?

Als ik helemaal eerlijk tegen je ben, zou ik nooit zeggen. U kunt nooit te voorzichtig zijn en waarschijnlijk zoeken naar argumenten voor elke functie en elke vermenging van uw toepassing. Dat is waarschijnlijk niet noodzakelijk. Ik heb een gouden regel als het gaat om argumentcontrole: als de Sass-compiler waarschijnlijk door de waarde wordt gecrasht, moet u het hebben gecontroleerd

Dat betekent dat als je een mix hebt die argumenten accepteert die rechtstreeks worden gebruikt als waarden voor CSS-eigenschappen, ik denk niet dat het zinvol is om ze agressief te controleren. Het worstcasescenario is dat die waarden in de CSS-uitvoer worden gedumpt, wat resulteert in ongeldige CSS die niet door de browser wordt begrepen. Afgezien van een aantal extra bytes die worden geladen, zal er niet veel schade zijn.

Overweeg bijvoorbeeld de volgende mixin:

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

En overweeg nu het volgende gebruik:

.element @omvang grootte (10, "string"); 

De resulterende CSS zal zijn:

.element width: 10; hoogte: "string"; 

Elke browser weigert eenvoudig beide eigenschappen omdat hun waarden ongeldig zijn. Geen probleem.

Fouten in diep geneste functies verwerken

Met wat we zojuist hebben gezien, zou je 99% van de mogelijke fouten correct moeten kunnen verwerken, hoe dan ook is een geval waarbij het moeilijker wordt om Sass bij te houden: bij het omgaan met fouten van een functie die wordt aangeroepen vanuit een functie die wordt gebeld vanuit een functie ...

Ik zag precies hetzelfde toen ik SassyJSON schreef, een JSON-parser geschreven in Sass. In principe geef je een JSON-tekenreeks door aan de json-decode functie, die deze doorgeeft aan de  _json-decode - waarde functie, die het vervolgens doorstuurt naar a _json-decode - * functie afhankelijk van het type waarde dat wordt geparseerd. Hoe dan ook, het was niet ongewoon dat ik drie, vier, misschien vijf functie-aanroepen in elkaar had genest.

Helaas is er in zo'n geval geen schone manier om de uitvoering te stoppen. Je moet je fouten tot het hoogste niveau laten borrelen door de functie-terugkomst op elk niveau handmatig te controleren. Als u bijvoorbeeld een fout in de diepste functie hebt, moet deze false retourneren naar de aanroepende functie, die deze waarde vervolgens moet controleren en zich realiseren dat het vals, dus val false in de bovenste functie, enzovoort, totdat je de hoogste hebt bereikt die de uitvoering stopt.

Dat is best lastig om mee om te gaan, maar er is geen keuze. Dat gezegd hebbende, als je verschillende niveaus van functies moet nesten, zou ik zeggen dat je Sass niet correct gebruikt.

Wat te retourneren in geval van een fout

Wanneer er iets misgaat, kunt u verschillende waarden retourneren, vals en nul de meest populaire zijn. Ik veronderstel dat je terug zou kunnen komen -1 of ongeldig 0 als je van een JavaScript-achtergrond komt. Ik denk dat je ook zoiets zou kunnen teruggeven FOUTCODE hoewel dat de controle op een storing iets gecompliceerder zou maken.

Ik gebruik om terug te keren vals want dat spreekt voor zich: het is vals. Dit kan echter een probleem zijn met functies waarvan wordt verondersteld dat ze een boolean retourneren. Hoe zou je weten of de functie terugkeert? vals omdat het resultaat is geëvalueerd naar vals, of vals omdat er een fout is opgetreden?

U kunt dus besluiten om een ​​andere waarde te kiezen. Er is een interessant ding bij nul: een CSS-eigenschap met een waarde van nul zal niet worden gecompileerd naar de bron. In principe betekent dit dat als u een Sass-functie gebruikt als waarde voor een CSS-eigenschap en er iets mis is, de CSS-eigenschap eenvoudigweg wordt weggelaten door de Sass-compiler.

Ik denk dat dat eigenlijk best wel leuk is voor zoiets als dit:

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

Als de functie get-kleuren-van-thema is goed ontworpen, het moet ervoor zorgen dat het beheerder thema bestaat en is eigenlijk gebonden aan een kleurwaarde. Als beheerder bestaat niet, dan zou de functie terugkeren nul wat zou resulteren in achtergrond: null. Dit zorgt ervoor dat Sass de regel weglaat bij het compileren van het bestand naar CSS.

In Noodzaak van een gooien() Functie

De meeste talen hebben een gooien functie of richtlijn. Doorgaans accepteert deze functie een foutbericht of een uitzondering als enige argument en stopt de uitvoering van het script om dit bericht weer te geven (in de console of zo) wanneer er een fout optreedt. Bijvoorbeeld in JavaScript, kunt u zoiets als dit doen:

if (typeof myVariable === "undefined") throw new userException ("'myVariable' moet worden gedefinieerd");  

Helaas heeft Sass dit niet. In principe is er absoluut geen manier om een ​​functie of een mixin te stoppen in Sass. Je zou er een kunnen bouwen, maar het zou de functie praktisch niet stoppen, het zou alleen false opleveren en een bericht loggen.

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

In plaats van het handmatig te schrijven @waarschuwen richtlijn en de @return false elke keer kunt u de gebruiken gooien() functie onthoud echter dat het geen magie doet en het script ook niet stopt. Het retourneert eenvoudig 'false' en meldt een foutmelding.

Dat gezegd hebbende, met een gooien richtlijn is al een paar keer aan Sass-beheerders gevraagd en het lijkt erop dat ze het erover eens zijn dat het niet zo erg zou zijn om een ​​te implementeren @fout richtlijn die de huidige uitvoering van de scope zou verbreken volgens nummer # 747. Misschien voor 3.4, weet ik het niet zeker.

Laatste gedachten

Ongeacht hoe je het doet, je moet altijd de functie en mixin inputs controleren in plaats van de compiler te laten crashen omdat er iets onverwachts is gebeurd. Als ontwikkelaar heb ik liever een schoon logboek en niets meer dan een enorm stacktracé, maar dat ben ik niet.

Als een levend voorbeeld, stel ik voor dat je een kijkje neemt in een kleine knoppenbibliotheek die ik enige tijd geleden heb gebouwd. Het grootste deel van de code uit de kernmix is ​​argumentcontrole en foutafhandeling. Het zorgt ervoor dat de mix er vol uitziet, maar ik denk dat het essentieel is voor ontwikkelaars die de code zullen gebruiken.

Zorg er uiteindelijk voor dat u iets bedenkt dat bij u en uw team past en u komt wel goed.