Jeffrey Cross
Jeffrey Cross

Codebox: Upravljanje iznimkama u obradi

U Codeboxu: Spremanje podataka senzora na Google Spreadsheets, čitatelj Stairs je primijetio da je skica eksplodirala kada nije imao spajani Arduino uređaj. Kad je iskopao uređaj, uključio ga i ponovno pokrenuo crtež, dobro je funkcionirao.

Ovo ilustrira veliku točku o obradi, programiranju i životu općenito: živimo u nesavršenom svijetu. Lijepe male skice započinju s uključivanjem Arduina, brojevi se dijele na nulu, ljudi trče škarama i tako dalje i tako dalje. U Obradi se nazivaju takvi uvjeti iznimke, a ovaj post pruža blagi uvod o tome kako postupati (ili, službeno, rukovati) njih. (Napomena: ovaj post neće spriječiti trčanje škarama.)

Dakle, prvo, kako vas obrada obavještava kada nešto nije u redu? Općenito (ako nešto nije u velikoj mjeri pogrešno!), Pokrenut ćete skicu, a zatim vidjeti nešto poput sljedećeg:

Obratite pažnju na sve crvene poruke o pogreškama u području poruka, gdje vam obrada govori o tome što nije u redu. U ovom slučaju, pogreška je PortInUseException (), koji, ako pokrenete Google, pronaći ćete nešto ugledno u obradi. (Više o ovome kasnije.) U poruci se također navodi na kojoj je liniji pogreška bačen, Uz to, linija vrijeđanja označena je žutom bojom u uređivaču teksta. Ovisno o tome gdje se pogreška pojavljuje, prozor skice se može ili ne mora pojaviti, pa čak i ako je vidljiv, gotovo sigurno neće učiniti ono što očekujete.

Da biste reproducirali ovu pogrešku (ili sličnu - pogledajte odjeljak upozorenja na dnu posta!), Zalijepite tekst za simple_port.pde u Obradu. Ako sve prođe dobro, skica čita serijski port jednom u sekundi i prikazuje proteklo vrijeme i vrijednost koja se čita iz porta.

Naravno, ne želimo da sve ide dobro (to je svrha ovog posta), stoga provjerite je li vaš Arduino isključen kada pokrenete skicu. Trebali biste vidjeti nešto slično prethodnoj slici. Sada smo spremni dodati kôd za obradu (ili rukovatikoji je formalni izraz) nepovezani uređaj.

Da bismo obradili iznimku u Obradi (i Java, od kojih je Obrada podskup), postavljamo sumnjivi kod unutar bloka "pokušaj-uhvatiti-konačno". Obrada zatim "pokušava" izvršiti kôd, a ako su izuzete bilo kakve iznimke, one su "uhvaćene" drugim blokovima. Sintaksa izgleda ovako:

pokušaj { Osumnjičeni kôd koji želite pokušati izvršiti ...} catch (ExceptionType1 e1) { // kod za izvođenje ako je ExceptionType1 izbačen u probnom bloku println (e1.getMessage ()); ...} catch (ExceptionType1 e2) { // kod za izvođenje ako je ExceptionType2 izbačen u probnom bloku println (e2.getMessage ()); ...} catch (ExceptionType3 e3) { // kod za izvođenje ako je ExceptionType3 izbačen u probnom bloku println (e3.getMessage ()); ...} konačno { // Očistite ovdje kod ... }

Budući da iznimke nisu obuhvaćene Početkom rada s obradom, dopustite mi da odgovorim na nekoliko općih pitanja koja možda imate:

  • Kako to misliš? sumnjivi kod? U početku, možda mislite da je cijeli kôd sumnjiv, ali se rukovanje iznimkama uglavnom koristi u nekoliko ključnih okolnosti, kao što su čitanje ili pisanje u datoteku, povlačenje podataka preko mreže ili komunikacija s uređajem (poput serijskog porta). Zapravo, mnoge knjižnice zahtijevaju da neke metode stavite u blok za pokušaj ili ga uopće neće kompajlirati. Na primjer, ako ste uklonili blok pokušaja iz koda Google proračunske tablice, program ne bi ni kompajlirao. Knjižničari to čine kako bi programatore natjerali na dobre navike.
  • Što su sve te izjave o ulovu? Budući da kôd može poći po zlu na sve moguće načine, moramo biti u stanju nositi se s mnogo različitih mogućnosti. Dakle, svaka izjava o ulovu povezana je s jednom određenom vrstom pogreške. Ako se pojavi određena vrsta pogreške, tada se izvršava odgovarajući blok koda. Na primjer, pretpostavimo da ste pokušali pročitati neke podatke iz datoteke. Datoteka jednostavno ne postoji, što baca a FileNotFoundException iznimka. Ili datoteka možda postoji, ali nekako postaje nedostupna dok je čitate. Ovo baca EOFException, Ili, nešto jednostavno čudno se događa u IO potoku, koji baca grad-mariju IOException, Za svaku od ovih okolnosti možete stvoriti blok za ulov. Možda je najbolja analogija blok if-then-else opisan na stranici 64 knjige Getting Started.
  • Što znače stvari u zagradama nakon ulova? To su kao argumenti za funkciju - prvi token identificira vrstu iznimke koja bi trebala uzrokovati pucanje bloka, a druga je varijabla koja vam omogućuje pristup podacima i metodama iznimke. (Iznimke, kao i sve u Obradi, su objekti.) Na primjer, ako ste imali liniju poput ove - catch (FileNotFoundException e), taj bi se blok izvršio ako kôd u bloku za pokušaj nije mogao pronaći datoteku koju ste tražili. Unutar bloka imat ćete naziv varijable e koje biste mogli iskoristiti da saznate više o tome što se događa. Na primjer, možete upotrijebiti njegov getMessage () način ispisa pojedinosti o pogrešci u područje za poruke
  • Je li redoslijed izvješća o ulovu važan? Da. Obrada će ispaliti prvi blok ulova koji odgovara klasi iznimke ili nadklasi. Budući da su objekti hijerarhijski, to znači da su neke iznimke više u hranidbenom lancu od drugih. Slijedom toga, oni odgovaraju gotovo svemu. (Naziva se najviša klasa izuzetka izuzetakDakle, trebate staviti najprirodnije iznimke najprije i opće iznimke kasnije.
  • Što znači “konačno”? konačno blok je opcionalan i omogućuje dodavanje koda koji će stalno izvršava, pojavljuje li se pogreška ili ne. To se obično koristi za čišćenje koda. Na primjer, ako otvorite datoteku, možda ćete je htjeti zatvoriti u blok za konačno.
  • Što ako nemam točnu vrstu pogreške u svojim blokovima ulova? Kratak odgovor je da vaš program eksplodira. Ovo je situacija koja se naziva neobrađena iznimka, općenito je ono što pokušavate izbjeći. Kao konačni ulov, možete jednostavno dodati ulov (Iznimka e) kao konačni blok za ulov. Ovo je najopćenitiji tip objekta iznimke, tako da bi trebao uhvatiti većinu pogrešaka.

Fijuk. Dosta teorije. Vratimo se izvornom problemu sprječavanja širenja našeg koda. (Ipak, samo smo izgrebali površinu. Ako želite saznati više, pogledajte lekciju: Iznimke, odličan vodič iz Oraclea.)

Budući da naš kôd raste na liniji port = novi serijski (ovaj, arduinoPort, 9600);, ovo je prilično očito mjesto za postavljanje probnog bloka. Ono što želimo da uradimo je da testiramo ima li ikakvih iznimaka na ovoj liniji (ne zanima nas što), a ako ih ima, prikažite poruku "Plug in Arduino". Čim je Arduino priključen, želimo početi prikazivati ​​brojač i trenutnu vrijednost iz serijskog porta. Evo revidirane verzije koda, simple_port2.pde, koja to čini.

Kada pokrenete ovaj kôd, trebali biste vidjeti nešto slično sljedećoj slici.

Dakle, što se događa ovdje? Prva stvar koju ćete primijetiti je da sam premjestio uvredljivu liniju iz postaviti() metoda i na crtati() metoda. Time se osigurava da skica opetovano provjerava je li Arduino pronađen; obaviti test postaviti() bi značilo da se to događa samo jednom, kada skica počinje. Zatim sam stvorio zastavu ardinoOK - ako je ova zastavica netočna, želimo pokušati zgrabiti port i prikazati poruku o pogrešci. Ako je zastava istinita, onda želimo pročitati port i prikazati vrijednosti. Konačno, ugradio sam port = novi serijski (ovaj, arduinoPort, 9600); linija unutar probnog bloka. Ako naredba uspije, onda smo postavili arduinoOK to true. Ako dođe do iznimke, uhvatit ćemo je s ulov (Iznimka e) blokirati i postaviti arduinoOK to false. Budući da je ovaj kod unutra crtati(), ponavlja tu logiku iznova i iznova. Voila!

upozorenja

Kako sam nagovijestio, obrada iznimaka za ovaj projekt bila je malo teška. Na primjer, stepenice (čitatelj čiji je komentar objavio ovaj post) prijavile su ArrayIndexOutOfBoundsExeption, To je podrazumijevalo da je kod eksplodirao Niz arduinoPort = Serial.list () [0]:, što znači da nije bilo uređaja. "Ha", pomislio sam, samo ću testirati tu iznimku. Međutim, kad sam ga pokrenuo na svom Macu, pronašao sam nekoliko uređaja koji su već na popisu, tako da nije eksplodirala s istom pogreškom koja je dobila Stepenice. Dodavanje u Arduino samo je dodalo dvije nove stavke na popis, kao što je prikazano u sljedećoj tablici.

Arduino nije instaliran Arduino instaliran
Stabilna knjižnica ========================================= Native lib Version = RXTX-2.1 -7 Java lib Version = RXTX-2.1-7 [0] "/dev/tty.Bluetooth-Modem" [1] "/dev/cu.Bluetooth-Modem" [2] "/dev/tty.Bluetooth-PDA- Sinkronizacija "[3]" /dev/cu.Bluetooth-PDA-Sync " Stabilna knjižnica ========================================= Native lib Version = RXTX-2.1 -7 Java lib Version = 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 "Eksperimentalno: JNI_OnLoad je pozvan.

Malo Googlinga pokazalo je da Macovi imaju nekoliko procesa koji se po defaultu pokreću kako bi pokupili nove uređaje, kao što su kamere ili Bluetooth uređaji. Stoga sam zaključio da stepenice moraju biti na računalu, koje nisu imale te stavke.

No, moj je kôd još uvijek eksplodirao, ali za drugu pogrešku: gnu.io.PortInUseException, "Ha!", Ali ja to mogu samo uhvatiti. Ali, to također nije uspjelo. Googling okolo, otkrio sam da se čini da postoji čudan bug na OS X koji čini hvatanje ovu iznimku problematično, i da morate ponovno instalirati ili izbrisati različite dijelove Serial knjižnice kako bi ih raditi. Dakle, ni to nije uspjelo. Konačno, odlučio sam se uhvatiti najopćenitije izuzetak kako bi ga natjerao da radi.

Tada sam htio učiniti nešto više o tome kako ćete uhvatiti pogreške tijekom pokretanja skice. Konkretno, htio sam obraditi slučaj kada je Arduino priključen, skica se pokreće, a vi je isključite iz srednjeg toka. Međutim, kada sam pokušao ovo, dobio sam ovu poruku o pogrešci koja se činila kao da dolazi iz operativnog sustava:

Budući da se njime rukovalo više u hranidbenom lancu, pogreška se nikada nije pojavila u obradi kao iznimka, pa je skica samo veselo zviždala. Hmmm, pomislio sam. Dakle, malo Googlinga otkrilo je da je vrlo loše raditi ono što sam planirala, i da to može dovesti do svih vrsta problema. Dakle, pretpostavljam da Mac ima ugrađene zaštitne mehanizme kako bi spriječio probleme nizvodno. Pretpostavljam da bih trebao biti zahvalan, ali to me je zbunilo za ovaj primjer.

Sve to pokazuje da to može biti stvarno, stvarno teško odrediti greške u programiranju jer ima toliko složenosti i međuovisnosti. Mislim da je to vjerojatno razlog zašto mnogi programeri postaju tvorci. U profesiji u kojoj 6 mjeseci može biti vječnost, zadovoljstvo je znati da bi strojevi koje izrađujete iz zupčanika i poluga vjerojatno bili razumljivi Aristotelu. Iskreno, nevjerojatno je da svijet teče jednako glatko kao i on.

Hvala vam, rukovatelji iznimkama svugdje!

U skladištu za kavu:


Početak rada s obradom Naučite programiranje računala na jednostavan način s obradom, jednostavnim jezikom koji vam omogućuje da koristite kod za izradu crteža, animacije i interaktivne grafike. Programski tečajevi obično počinju s teorijom, ali ova knjiga omogućuje vam da skočite izravno u kreativne i zabavne projekte. Idealan je za svakoga tko želi naučiti osnovno programiranje i služi kao jednostavan uvod u grafiku za osobe s određenim vještinama programiranja.

Udio

Ostavite Komentar