En introduksjon til feilhåndtering i Sass

Uansett hvilket språk, bør feilene håndteres på en ren og enkel måte, enten det er til fordel for sluttbrukeren eller den neste utvikleren. Når du utfører en feilaktig handling på et nettsted, bør det ikke bare banke deg med en feilkode eller en feilkommando. Det skal advare deg med en eksplisitt melding om hva som skjer.

Dette bør ikke være noe annerledes når du koder for andre utviklere. Når du bygger et bibliotek, et rammeverk eller bare jobber i et lag, er du ikke den eneste som bruker koden. Sannsynligvis kan mange utviklere med svært forskjellige bakgrunner bruke koden din, og de burde ikke trenge å grave dypt inn i kilden og vendingene i tankene dine for å finne ut hva som skjer.

Det er derfor du bør håndtere feil på riktig måte. Selv i Sass. Selv når det samler seg til noe som er permisjon som CSS. Når du bygger en tilpasset funksjon eller en mixin, bør du alltid sørge for at alt fungerer som forventet, og når det ikke er tilfelle, bør du ta en annen vei. 

Jeg vet ikke for deg, men jeg liker ikke å la Sass-kompilatoren feile. Jeg vil helst ha en kul liten melding som forklarer at jeg har glemt et argument i stedet for å møte:

Lang historie kort: håndtere feil feil. Jeg skal vise deg hvordan.

Hva å sjekke?

Pass på at alle argumenter er angitt

En av de første tingene å gjøre når du bygger en funksjon, er å sørge for at alle argumenter er angitt. Dessverre vil Sass ikke engang legge inn funksjonen hvis antall argumenter som er overført til det er feil. Heldigvis håndterer kompilatoren det på en fin måte med en melding som: Mixin my awesome-mixin mangler argument $ the-awesome-argumentet. så det er ikke så ille.

Hvis du ikke vil forlate dette i kompilatorens hender, og helst vil håndtere det på egen hånd, kan du omgå det ved å angi standardparametere for alle argumenter fra funksjonen / mixin. Ikke bare er det bedre for sluttbrukeren ikke å måtte spesifisere alle argumenter hver en gang, men det tillater deg også å utløse mixin / funksjonen i alle tilfeller, og gjøre hva som skal gjøres.

Å sørge for argumenter er gyldige

Det viktigste er nå å sørge for at alle argumenter er gyldige. For eksempel, hvis du trenger en farge, må du sørge for at utvikleren faktisk overfører en farge til funksjonen og ikke et tall eller en streng. Hvis du trenger en liste over tre verdier, bør du sjekke lengden for å være sikker på det er tre verdier, ikke to eller fire. 

Heldigvis gjør Sass det veldig enkelt å gjøre dette med en rekke standardfunksjoner, inkludert type-av () for å kontrollere datatypen til en verdi. Forresten, Sass 3.4 bør til og med introdusere er-type-av ($ verdi, $ type) å jobbe rundt spørsmålet om testing type () som alltid kommer tilbake liste mens det også kan være et kart.

Uansett, selv når du skriver et stykke kode for utviklere med en anstendig kjennskap til Sass, bør du være oppmerksom på inngangen til dine funksjoner. 

For eksempel når du gjør $ verdi: $ input + "px", du støtter i utgangspunktet et nummer (hvis $ inngang er et tall, åpenbart) til en streng. Så hvis du prøver å gjøre $ verdi * 2, Sass vil kaste en feil fordi du prøver å formere en streng. Mer informasjon om dette fenomenet i denne artikkelen.

... i en funksjon

Å håndtere feil i tilfelle en tilpasset funksjon er faktisk ganske enkelt: du kontrollerer hva som må kontrolleres. Hvis tilstanden ikke stemmer, kommer du tilbake falsk (eller null, se nedenfor) og advare brukeren med hjelp fra @varsle Sass-direktivet.

@function add-10 ($ nummer) @if type-of ($ number)! = "number" @warn "'# $ number' er ikke et antall 'add-10'."; @return false;  @return $ nummer + 10; 

I dette (ganske dumt er jeg enig), hvis $ nummer argumentet er ikke et tall, funksjonen kommer tilbake falsk og brukeren vil bli advart om at de har bestått et feil argument ved en melding som vises i deres terminal: 'SWAG' er ikke et tall for 'add-10'.

Hvis argumentet er gyldig, returnerer det bare tallet + 10. Enkelt som kake.

... i en mixin

Når du arbeider med en mixin, er det litt mer komplisert fordi du ikke faktisk returnerer noe; i stedet dumper du CSS-regler. For å løse problemet må du erklære en boolsk som tjener som en gyldighetskontroller. Vær oppmerksom på følgende eksempel:

@mixin-modulen ($ navn) // Initialiser en validitetskryter boolean $ alt-okay: true; // Kontroller argumentets gyldighet @if type av ($ navn)! = "Streng" @warn "'# $ name' er ikke en streng for 'modul'."; $ alt-okay: false;  // Hvis alt er fortsatt greit, dump mixin innhold @if $ alt-ok @content; 

Et ord om liste

Når du vil sørge for at en av argumentene er en liste med flere elementer i den, bør du alltid teste lengden i stedet for datatypen. For å si det enkelt, behandler Sass alle verdier som enkeltelementlister, og i noen tilfeller kan du finne deg selv med en enkelt gjenstandsliste som faktisk er fortsatt en liste.

På den annen side, et potensielt problem når du sjekker lengde er at det kan være en kart også. En måte å gjøre helt sikker på at du står overfor en liste over flere verdier, er å gjøre det slik:

@if lengde ($ verdi)> 1 og type av ($ verdi)! = kart // Det er en liste over flere verdier

Når sjekker for mye sjekking?

Hvis jeg er helt ærlig med deg, vil jeg aldri si det. Du kan aldri være for forsiktig og kunne sannsynligvis sjekke om noe argument for enhver funksjon og hvilken som helst blanding av søknaden din. Men det er sannsynligvis ikke nødvendig. Jeg har en gylden regel når det gjelder argumentkontroll: hvis verdien sannsynligvis vil gjøre Sass-kompilatoren krasj, bør du ha sjekket den

Det betyr at hvis du har en mixin som aksepterer argumenter som brukes direkte som verdier for CSS-egenskaper, tror jeg ikke det er noe poeng i å kontrollere dem aggressivt. Det verste fallet er at disse verdiene vil bli dumpet i CSS-utgangen, noe som resulterer i ugyldig CSS som ikke forstås av nettleseren. Bortsett fra et par ekstra bytes lastet, vil det ikke være mye skade.

For eksempel vurdere følgende mixin:

@mixin størrelse ($ bredde, $ høyde: $ bredde) bredde: $ bredde; høyde: $ høyde; 

Og nå vurdere følgende bruk:

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

Den resulterende CSS vil være:

.element bredde: 10; høyde: "streng"; 

Enhver nettleser vil ganske enkelt avvise begge egenskaper fordi deres verdier er ugyldige. Ingen stor sak.

Håndtering av feil i dypt nestede funksjoner

Med det vi nettopp har sett, bør du kunne håndtere 99% av mulige feil, men der er et tilfelle der det blir vanskeligere å holde følge med Sass: når man arbeider med feil fra en funksjon kalt fra en funksjon kalt fra en funksjon ...

Jeg konfronterte dette med SassyJSON, en JSON-parser skrevet i Sass. I utgangspunktet sender du en JSON-streng til JSON-dekode funksjon, som relayer den til  _json-dekode - verdi funksjon, som deretter relayer den til a _json-dekode - * funksjon avhengig av typen av verdien som blir analysert. Uansett var det ikke uvanlig at jeg hadde tre, fire, kanskje fem funksjonssamtaler nestet i hverandre.

Dessverre er det i så fall ingen ren måte å stoppe utførelsen av. Du må gjøre feilene dine boble til det øvre nivået ved å manuelt sjekke funksjonen tilbake på hvert nivå. For eksempel, hvis du har en feil i den dypeste funksjonen, bør den returnere falsk til kallfunksjonen, som da bør sjekke denne verdien, innse at den er falsk, så tilbake falsk til den øvre funksjonen, og så videre til du når den høyeste som deretter stopper kjøringen.

Det er ganske vondt å håndtere, men det er ikke noe valg. Når det blir sagt, hvis du må nest flere nivåer av funksjoner, vil jeg si at du ikke bruker Sass riktig.

Hva å returnere i tilfelle en feil

Når noe går galt, kan du returnere ulike verdier, falsk og null å være de mest populære. Jeg antar at du kunne komme tilbake -1 eller tomrom 0 hvis du kommer fra en JavaScript-bakgrunn. Jeg antar du kan også returnere noe sånt FEIL KODE selv om det ville gjøre kontrollen for en svikt litt mer komplisert.

Jeg bruker for å returnere falsk fordi det snakker for seg selv: det er falskt. Dette kan imidlertid være et problem med funksjoner som skal returnere en boolsk. Hvordan vil du vite om funksjonen returnerer falsk fordi resultatet har blitt vurdert til falsk, eller falsk fordi det har vært en feil?

Dermed kan du bestemme deg for å velge en annen verdi. Det er en interessant ting med null: en CSS eiendom med en verdi på null vil ikke bli kompilert til kilden. I utgangspunktet betyr det at hvis du bruker en Sass-funksjon som en verdi for en CSS-egenskap og noe er galt, vil CSS-eiendommen enkelt utelates av Sass-kompilatoren.

Jeg tror det er faktisk fint for noe slikt:

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

Hvis funksjonen få-farge-fra-tema har blitt godt utformet, det bør sørge for at admin temaet eksisterer og er faktisk bundet til en fargeverdi. Hvis admin eksisterer ikke, da vil funksjonen returnere null som ville resultere i bakgrunn: null. Dette vil gjøre Sass omgå regelen når du kompilerer filen til CSS.

I nød av en kaste() Funksjon

De fleste språk har a kaste funksjon eller direktiv. Vanligvis aksepterer denne funksjonen en feilmelding eller et unntak som bare argument og stopper bare utførelsen av skriptet for å vise denne meldingen (i konsollen eller noe) når det oppstår en feil. For eksempel i JavaScript, kan du gjøre noe slikt:

hvis (type av myVariable === "undefined") kaste ny brukerException ("'myVariable' bør defineres");  

Dessverre har Sass ikke dette. I utgangspunktet er det absolutt ingen måte i Sass å stoppe en funksjon eller en blanding fra å utføre. Du kan bygge en, men det ville ikke praktisk talt stoppe funksjonen, det ville bare returnere falskt og logge en melding.

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

I stedet for å skrive manuelt @varsle direktiv og @return false hver gang kan du bruke kaste() funksjon men husk at det ikke gjør noen magi heller ikke stopper skriptet fra å kjøre. Den returnerer bare 'false' og logger en feilmelding.

Som sagt, ha en kaste Direktivet er blitt spurt ganske mange ganger til Sass-vedlikehavere, og det virker som om de har blitt enige om at det ikke ville være så ille å implementere en @feil direktiv som ville bryte gjeldende omfangsutførelse i henhold til nummer # 747. Kanskje for 3,4, er jeg ikke sikker.

Siste tanker

Uansett hvordan du gjør det, bør du alltid sjekke funksjonen og mixin-inngangene i stedet for å la kompilatoren krasje fordi den opplever noe uventet. Som en utvikler vil jeg helst ha en ren logg og ikke noe utgang heller enn et stort stakkespor, men igjen er det ikke meg.

Som et levende eksempel foreslår jeg at du ser på et lite knappebibliotek jeg bygget litt tid tilbake. Mesteparten av koden fra kjernemixin er argumentkontroll og feilhåndtering. Det gjør mixin ser overfylt, men jeg synes det er viktig for utviklere som vil bruke koden.

Til slutt skal du bare sørge for at du kommer opp med noe som passer både deg og ditt lag, og du får det bra.