Kodekasse: Håndtering unntak i behandling - 💡 Fix My Ideas

Kodekasse: Håndtering unntak i behandling

Kodekasse: Håndtering unntak i behandling


Forfatter: Ethan Holmes, 2019

I kodeboks: Lagre sensordata til Google Spreadsheets, leser trapper observert at skissen blåste opp da han ikke hadde en Arduino-enhet koblet til. Da han gravd ut enheten, plugget den inn og startet skissen, fungerte den bra.

Dette illustrerer et flott poeng om bearbeiding, programmering og liv generelt: vi lever i en ufullkommen verden. Fint, små skisser kommer i gang uten Arduino plugget inn, tallene er delt med null, folk løper med saks, og så videre og så videre. Under behandling kalles forhold som disse unntakene, og dette innlegget gir en forsiktig introduksjon om hvordan man skal håndtere (eller, mer offisielt, håndtak) dem. (NB: dette innlegget forhindrer ikke å kjøre med saks.)

Så, for det første, hvordan kan behandling gi deg beskjed når noe har gått virkelig galt? Generelt (med mindre noe har gått veldig galt!), Starter du skissen og ser så noe som følgende figur:

Legg merke til alle de røde feilmeldingene i meldingsområdet, der hvor Processing forteller deg hva som har gått galt. I dette tilfellet er feilen PortInUseException (), som, hvis du starter Googling, finner du noe av et rutet rykte i Processing. (Mer om dette senere.) Meldingen forteller deg også hvilken linje feilen var kastet. I tillegg er den overordnede linjen uthevet i gul i tekstredigeringsprogrammet. Avhengig av hvor feilen oppstår, kan skissevinduet kanskje vises, og selv om det er synlig, vil det nesten ikke gjøre det du forventer.

For å reprodusere denne feilen (eller en som den - se delen for forbehold nederst i innlegget!), Lim inn teksten for simple_port.pde til Behandling. Hvis alt går bra, leser skissen serieporten en gang i sekundet, og viser den forløpte tiden og verdien som leses fra porten.

Selvfølgelig vil vi ikke at alt skal gå bra (det er poenget med dette innlegget), så sørg for at Arduino er koblet fra når du kjører skissen. Du bør se noe som ligner den forrige figuren. Nå er vi klare til å legge til kode for å håndtere (eller håndtak, som er det formelle begrepet) den frakoblede enheten.

For å håndtere et unntak i Behandling (og Java, hvorav Processing er en delmengde), plasserer vi den mistenkte koden i en "try-catch-finally" blokk. Behandler da "prøver" å utføre koden, og hvis noen unntak kastes, blir de "fanget" av andre blokker. Syntaxen ser slik ut:

prøv { Den mistenkte koden du vil prøve å utføre ...} catch (ExceptionType1 e1) { // kode som skal utføres hvis ExceptionType1 kastes i prøveblokken println (e1.getMessage ()); ...} fangst (UnntakType1 e2) { // kode for å utføre hvis ExceptionType2 er kastet i forsøksblokken println (e2.getMessage ()); ...} fangst (UnntakType3 e3) { // kode som skal utføres hvis ExceptionType3 kastes i prøveblokken println (e3.getMessage ()); ... } endelig { // Oppryd kode her ... }

Siden unntak ikke er dekket i Komme i gang med behandling, la meg svare på noen generelle spørsmål du måtte ha:

  • Hva mener du med mistenkelig kode? I utgangspunktet kan du tro at all kode er mistenkt, men unntakshåndtering brukes for det meste i noen viktige omstendigheter, for eksempel å lese eller skrive til en fil, trekke data over et nettverk, eller kommunisere med en enhet (som en seriell port). Faktisk krever mange biblioteker at du vedlegger bestemte metoder i en prøvefeltboks, eller koden vil ikke kompilere i det hele tatt. Hvis du for eksempel fjernet forsøksblokken fra google regnearkskoden, ville programmet ikke engang kompilere. Bibliotekdesignere gjør dette for å tvinge programmører til gode vaner.
  • Hva er alle som fanger uttalelser om? Siden kode kan gå galt på alle måter, må vi kunne håndtere mange forskjellige muligheter. Så, hver fangstoppgave er knyttet til en bestemt type feil. Hvis den spesifikke typen feil oppstår, utføres den tilsvarende kodekoden. For eksempel, anta at du prøvde å lese noen data fra en fil. Filen kan ganske enkelt ikke eksistere, som kaster a FileNotFoundException unntak. Eller, filen kan eksistere, men på en eller annen måte blir den utilgjengelig mens du leser den. Dette kaster en EOFException. Eller, noe som bare er rart, skjer i IO-strømmen, som kaster en hagelmary IOException. Du kan lage en fangstblokk for hver av disse forholdene. Kanskje den beste analogien er if-then-else-blokkene som er beskrevet på side 64 i Komme i gang-boken.
  • Hva betyr ting i parentes etter fangst? Disse er som argumenter for en funksjon - den første token identifiserer typen unntak som burde få blokkene til å brann, og den andre er en variabel som lar deg få tilgang til unntakets data og metoder. (Unntak, som alt i Behandling, er objekter.) Hvis du for eksempel hadde en linje som dette - fange (FileNotFoundException e), vil denne blokken utføres hvis koden i prøveblokken ikke kunne finne en fil du lette etter. Inne i blokken vil du ha en variabel som heter e som du kan bruke til å finne ut mer om hva som gikk galt. For eksempel kan du bruke det GetMessage () metode for å skrive ut detaljene av feilen til meldingsområdet
  • Fanger rekkefølgen av fangstopplysningene? Ja. Behandling vil brenne den første fangstblokk som samsvarer med unntakets klasse eller superklasse. Siden objekter er hierarkiske, betyr det at enkelte unntak er høyere opp i næringskjeden enn andre. Følgelig matcher de nesten alt. (Den høyest rangerte unntaksklassen kalles Unntak, som matcher alt.) Så du må sette de mest spesifikke typene unntakene først og flere generelle unntak senere.
  • Hva betyr "endelig"? De endelig blokk er valgfritt og lar deg legge til kode som vil alltid utfører, om det oppstår en feil eller ikke. Dette brukes vanligvis til oppryddingskode. Hvis du for eksempel åpner en fil, vil du kanskje lukke den i sluttblokken.
  • Hva om jeg ikke har den eksakte typen feil i mine fangstblokker? Det korte svaret er at programmet ditt kommer opp. Dette er en situasjon, som kalles en ubehandlet unntak, er generelt det du prøver å unngå. Som en endelig fangst alle, kan du bare legge til en fange (unntak e) som den endelige fangstblokken. Dette er den mest generiske typen unntaksobjekt, så det bør ta mest feil.

Puh. Nok teori. La oss gå tilbake til det opprinnelige problemet med å forhindre at vår kode blåses opp. (Vi har fortsatt bare riper på overflaten. Hvis du vil lære mer, sjekk ut leksjon: unntak, en god opplæring fra Oracle.)

Siden vår kode blåser opp på linjen port = ny seriell (dette, arduinoPort, 9600);, dette er et ganske åpenbart sted å sette en try-catch blokk. Hva vi vil at koden skal gjøre er å teste om det er noen unntak i det hele tatt på denne linjen (vi bryr oss egentlig ikke om hva), og hvis det er, viser en "Plug in Arduino" melding. Så snart en Arduino er koblet til, vil vi begynne å vise telleren og gjeldende verdi fra seriell port. Her er en revidert versjon av koden, simple_port2.pde, det gjør dette.

Du bør se noe som følgende figur når du kjører denne koden.

Så hva skjer her? Det første du vil legge merke til er at jeg flyttet den fornærmende linjen ut av setup () metode og inn i tegne() metode. Dette sørger for at skissen gjentatte ganger vil teste om Arduino er funnet; gjør testen i setup () ville bety at det bare skjer en gang, når skissen starter. Deretter har jeg opprettet et flagg som heter ardinoOK - Hvis dette flagget er feil, vil vi prøve å ta tak i porten og vise feilmeldingen. Hvis flagget sant sant, vil vi lese porten og vise verdiene. Til slutt har jeg innebygd port = ny seriell (dette, arduinoPort, 9600); linje inne i en prøvefelt blokk. Hvis kommandoen lykkes, setter vi inn arduinoOK til sant. Hvis et unntak oppstår, fanger vi det med fange (unntak e) blokkere og sette arduinoOK å falle. Siden denne koden er inne tegne(), gjentar det denne logikken igjen og igjen. Voila!

Advarsler

Som jeg har antydet gjennom, har unntakshåndtering for dette prosjektet vært vanskelig å håndtere. For eksempel rapporterte trapper (leseren hvis kommentar sparket av dette innlegget) en ArrayIndexOutOfBoundsExeption. Det innebar at koden var blåser opp på String arduinoPort = Serial.list () [0]:, som indikerer at det ikke var noen enheter. "Ha," tenkte jeg, jeg skal bare teste for det unntaket. Men da jeg kjørte den på min Mac, fant jeg flere enheter allerede på listen, så det var ikke blåser opp med den samme feilen Trappene fikk. Plugg i Arduino lagde bare to nye elementer til listen, som vist i tabellen nedenfor.

Ingen Arduino installert Arduino installert
Stabilt bibliotek ============================================================================================================ -7 Java lib Versjon = RXTX-2.1-7 [0] "/dev/tty.Bluetooth-Modem" [1] "/dev/cu.Bluetooth-Modem" [2] "/dev/tty.Bluetooth-PDA- Synkroniser "[3]" /dev/cu.Bluetooth-PDA-Sync " Stabilt bibliotek ============================================================================================================ -7 Java lib Versjon = RXTX-2.1-7 [0] "/dev/tty.usbmodem1d11" [1] "/dev/cu.usbmodem1d11" [2] "/dev/tty.Bluetooth-Modem" [3] " /dev/cu.Bluetooth-Modem "[4]" /dev/tty.Bluetooth-PDA-Sync "[5]" /dev/cu.Bluetooth-PDA-Sync "Eksperimentell: JNI_OnLoad kalles.

En del Googling indikerte at Macs har et par prosesser som kjører som standard for å hente nye enheter, som kameraer eller Bluetooth-enheter. Så jeg skjønte Trapper må være på en PC, som ikke hadde disse elementene.

Men min kode var fortsatt blåser opp, men for en annen feil: gnu.io.PortInUseException. "Ha !," Jeg skjønner, jeg kan bare fange den. Men dette fungerte heller ikke. Googling rundt, oppdaget jeg at det synes å være en merkelig feil på OS X som gjør at dette unntaket er problematisk, og at du må installere eller slette ulike deler av Serial-biblioteket for å få dem til å fungere. Så det fungerte heller ikke. Til slutt bestemte jeg meg for å fange den mest generiske Unntak å få det til jobb.

Da ville jeg gjøre litt mer om hvordan du ville ta feil mens skissen kjørte. Spesielt ønsket jeg å håndtere saken der Arduino er koblet inn, skissen begynner å løpe, og du kobler den fra midtstrømmen. Men da jeg prøvde dette, fikk jeg denne feilmeldingen som syntes å komme fra operativsystemet:

Siden det ble håndtert høyere opp i næringskjeden, svømte feilen aldri ned i Behandlingen som et unntak, så skissen bare hummet sammen glatt. Hmmm, tenkte jeg. Så, en del av Googling viste at det er veldig ille å gjøre det jeg planla, og at det kan føre til alle slags problemer. Så, jeg antar at Macen har sikkerhetskontroller innebygd for å forhindre problemer nedstrøms. Jeg antar jeg burde være takknemlig, men det bummed meg ut for dette eksempelet.

Alt dette viser at det kan være veldig, veldig vanskelig å klemme ned programmeringsfeil fordi det er så mange kompleksiteter og gjensidig avhengighet. Jeg tror dette er sannsynligvis hvorfor så mange programmerere blir Makers. I et yrke hvor 6 måneder kan være en evighet, er det tilfredsstillende å vite at maskinene du bygger ut av gir og spak ville trolig være forståelig for Aristoteles. Helt ærlig er det utrolig at verden går så jevnt som det gjør.

Takk, unntakshandlere overalt!

I Maker Shed:


Komme i gang med behandling Lær dataprogrammering på den enkle måten med Behandling, et enkelt språk som lar deg bruke kode for å lage tegninger, animasjoner og interaktiv grafikk. Programmeringskurs starter vanligvis med teori, men denne boken lar deg hoppe rett inn i kreative og morsomme prosjekter. Den er ideell for alle som ønsker å lære grunnleggende programmering, og fungerer som en enkel introduksjon til grafikk for folk med noen programmeringsferdigheter.



Du Kan Være Interessert

Kalender runde opp

Kalender runde opp


Kan 50 Lukkede Chicago Skoler Bli 50 Makerspaces?

Kan 50 Lukkede Chicago Skoler Bli 50 Makerspaces?


LeanKit TARDIS er en Timey-Wimey ting

LeanKit TARDIS er en Timey-Wimey ting


Pittsburgh Mini Maker Faire: En titt tilbake

Pittsburgh Mini Maker Faire: En titt tilbake






Siste Innlegg