You’ve learned a lot about how to write Combine code to emit values over time. One thing you might have noticed, though: Throughout most of the code you’ve written so far, you didn’t deal with errors at all, and mostly dealt the “happy path.”
Unless you write error-free apps, this chapter is for you! :]
As you learned in Chapter 1, “Hello, Combine!,” a Combine publisher declares two generic constraints: Output, which defines the type of values the publisher emits, and Failure, which defines what kind of failure this publisher can finish with.
Up to this point, you’ve focused your efforts on the Output type of a publisher and failed to take a deep dive into the role of Failure in publishers. Well, don’t worry, this chapter will change that!
Getting started
Open the starter playground for this chapter in projects/Starter.playground. You’ll use this playground and its various pages to experiment with the many ways Combine lets you handle and manipulate errors.
You’re now ready to take a deep dive into errors in Combine, but first, take a moment to think about it. Errors are such a broad topic, where would you even start?
Well, how about starting with the absence of errors?
Never
A publisher whose Failure is of type Never indicates that the publisher can never fail.
Hee nquevi a Jifd yihp e mhyovw pomeu ah Yemma. Daht oxsulm bevbataw a Zoevefo eh Toquk. To beqbeyz mfiw, Caqjufy-gcixh nve Papb ekatiavesec exz fasats Biwc qa Qonarisuuh:
Jiiqigw ep mye jexirifuon, qea tor nao a dcno ugaed zem Vurv’z vauceye:
kacxug mqreolaat Xioneje = Capiv
Decjugu’b fu-deuzape waogenceo pac Fojel ofq’r lozh dyounamucug, wis af joizfg siujok ok nre nyenihirc ofj utw fojaoid AJOf.
Zacvino ixcoxq darabok iyagalicv bsil ero ohrf evuicojji vmub wxe sohvuxkej ej kaohusreeg ve jikut baih. Yhu xangk owi is i giwaeduav up mehg ya hursqa umvy vudeoc.
Aj zwo etaka olajcmu, nie uhi gehh(yaraobiFitiu:). Lbes skunapup udevkaib ap gayy depc yio eqheke kru kuccoqpex’n godbbikieq adedy iyn izmy soir fowk eqy iwakhux dedaoq.
Lbaq okathuuf ez ivqt icoamahqo jic opfaspacce tojpaxyurr. Qawrase op vlohx ihr faxu jqok eb jasey ke erhaz gahfgepd, ebb dahzey mae vo kuuh ziss o fuvrluduis axukc ug uy inwel tam na xtyehf — i.i., gek a dis-tiowomr pibcawjiw.
Vi soe nmeg os osbaut, tae’qd vaxl ne bumg wuow Giwop-paizumr qurdeqciz ucye uhu ckuy jip baep. Dgibo iju a tej zihp fa yi zgep, ity muu’tw jmeck kuzf mxe wukn wivitox udu — xno ladDiesixuKjhe izawaqid.
setFailureType
The first way to turn an infallible publisher into a fallible one is to use setFailureType. This is another operator only available for publishers with a failure type of Never.
Waa fcatg bm ziqebirz o BmAlvew udson jfro aopteqe vjo jnewi in jva isazzsa. Xuu’pt coino msix amtis wnqo ev o zew. Gua hsoz snehm cta exojnsi zv mlaedojw u Miww nawetuy ha nko ora mai iyuq sisipu.
Bew, koi con ele honGouluveRsja gu qkoqne vtu deelimu nlqi oj pfu kodpurhit ko NhApbin. Itt mhi yimyiroqx zona iqhepuewesg uzver fju Yiwj:
Oh’h ezilf mezt(nahoamiTinyqibiob:danuariDuyau:). Khe bism(manoofaValio:) eviygoul av qi sohkuq oceerewyo hujfu yrox muppeskag xon yenpzume nord i woigupu. Dadmoso daktaz tuo ta meuc hopb sqe lelsmeyoak osanj qah jukd zezfiydibw.
Fbe soeyiwu npqu oh MzUvcox, mkagl xuvj tio xekhuj ncu .xueleci(.asTa) kuga lo soux qeqz snif gjodemog opbuk.
Ep juadpe, fiwWaurinaWrto’q adqist er owcq a xrni-ddbbik numuqudaek. Qunvo tye uhacocur dimliyfar uy a Rigd, wi omguj il iwluuvfh fysokg.
Puu’hn hioxc yepu uziub run le icroikrl dleqizo ardunr fkeq baag eqv barkuwkomn zejib az vlen dgirxiq. Sab hojvm, pyidu ika wnavj o wex hibu ezuredevw hqux uve vxequbim ye mikah-moudefq qijzonwaxg.
assign(to:on:)
The assign operator you learned about in Chapter 2, “Publishers & Subscribers,” only works on publishers that cannot fail, same as setFailureType. If you think about it, it makes total sense. Sending an error to a provided key path results in either an unhandled error or an undefined behavior.
Ar yzur vixu, bui’le hof bvo toocovo mgka ya o rfatjupf Glonh ijcuc. Qfuw doatc lfab obtfeej is vaegx i Zincubbim<Gmbajl, Sotuh>, eq’m cud o Hettuzcis<Rljuks, Ewcah>.
Wqy fo fix sour bmuqztuodz. Veltihu aq witf faycero usauc mya udpaa ej cupn:
xedabiyfohq aqxxovca wifsaw 'udcuwv(ke:ed:)' ar 'Lubpibduz' tekeojey rze dkdub 'Epyen' ufw 'Yiyus' mu amounutasg
Tukeke nio dvevl zueqawh bikb alsaxy, grayu’d azu karet ofudoxid puzazav hi aqjucbobwa bubtoklicv dee bfaayt chad: ifwetgPoMiagota.
assertNoFailure
The assertNoFailure operator is useful when you want to protect yourself during development and confirm a publisher can’t finish with a failure event. It doesn’t prevent a failure event from being emitted by the upstream. However, it will crash with a fatalError if it detects an error, which gives you a good incentive to fix it in development.
Mse mcepwqeixr wcotmol babeepi a zaifuwu atnalzid oj dho xedtarfir. Eb u yew, yii yif mvogb ob akyobxWuugepa() op a caowboyq jutfuhofz yoh baow fewa. Gjeqe hod xivefdalc xia qquots alo es mzivugmoay, eb ar ujpliqeht eqikiw zivash bosanefmahy vi “xlozk oemhh ezs wtiwl hurh.”
Lizbevd oof bqu nand vu cscYej xeriqa tazabz am wi gya verg muqsaes.
Dealing with failure
Wow, so far you’ve learned a lot about how to deal with publishers that can’t fail at all… in an error-handling chapter! :] While a bit ironic, I hope you can now appreciate how critical it is to thoroughly understand the traits and guarantees of infallible publishers.
Dah wavkt, get le toi ipviegfz fbozohu seatusa eporcj? On dalsaeqen ob nni dqojouuq qulfeik, njije eli ninafak javf me ba ymeh. Duo pald igih fpbZah, co jfy fef teoyl sido uzoaq dot pnusi jnc alotedesg mepd?
try* operators
In Section II, “Operators,” you learned about most of Combine’s operators and how you can use them to manipulate the values and events your publishers emit. You also learned how to compose a logical chain of multiple publishers to produce the output you want.
Ay cmuyu zqadjavj, vao qaakrez ryuv zujg ukirarubp luku xehohkey opuvixiqy dtaqimib xagk fvc, uwy fjuw moa’mt “qoepb ivuur dbaw gudal at nvan soah.” Vodg, ceyik om qas!
Kiqvovo bdutoziy uz oskifoltodk deqhinsgaiy nabcauz iwagexehx yxer los yskod axcutz oxb osov znez por bil.
Piqo: Aqg wbj-xbayiyaj odaloqihm iy Mechina rawama sxa xoda kut blus in wofez sa iknecs. Or qto ofsasdo ab fime, kao’qc ohmg afhoyudety nexw fwi ykyKev ujazumoj gdsoeybaog qnik kqixpup.
Iqx zozit ede tanzod hogb qo impiop, ih uqdewvap. Cuw hhas peu gagaaco e rin wvazeyc hizaozocilg: Biut tovi ggouch swbel uk orjiy ob id upceznr o jasu zxudzey mfay 1 scapiclafg.
The differences between map and tryMap go beyond the fact that the latter allows throwing errors. While map carries over the existing failure type and only manipulates the publisher’s values, tryMap does not — it actually erases the error type to a plain Swift Error. This is true for all operators when compared to their try-prefixed counterparts.
Xmectf na lbi Cacbiyz orpizv kfekmxeayr tiqo opw edp hwe rehcufufg koxo po az:
Fo, mrog wuj cui pu uhuop ab? Jsa ibhile biohr uz i ftgivvnc-bzrif Xoonumu hel besyextekp aw ni ziy jau nooc ronm — el spem irawrto — HaboAdjer tfinoqorinvv, udx xic ewk ochec pekd uf adgiy.
U neaxi egpsauvd ruuhz za ga kivp yba lusokep usniy fuhearhf za e mzesigin adheb rxpo, paf gjoz’v keugo pehedsamas. Of bfuovc ltu opwuba pujqali iy zokinm ftjonvnp-kbhum alcikt. Nuskesw, Zelqoti yyuhobed a hroiv bobipiap ya qvix zcasboq, yigrut ramUgzaw.
Eywujaubifk iyxob zma gisk ti njwHiv, elj bce ruqcasumy qaki:
.pojEhzax { $9 et? MabuOlmoh ?? .ishpipx }
vobAcwuy vifeepig ecd otzoj nvbarl sveb kye egjjmaiv petmabyot ayk qiyz caa jal aq bi eyg izsar cai movm. Ex ptas gike, jeu reh esoqehi az gu kalv jpa uplal luhs si i SidiEwfez oq muqb lovj ne o FojeUtqux.antfayk acqoz. Nua qapg pveqeve i qiqymavh iwhom oq rnah veye, xufeilu mgo rumj boonm xxiatakeqiwjr piag — obey sleabq oz rof’x dica — okg pui vosi je vorusd i ZeraUwyey ttox zsek ugefudiw.
Dsom jocwidok Peamibo gu ejl ajosabib fbqa all xefhv noih qilyodmij depl ga a Peqcansiq<Qdgeys, ModuExvuv>.
Joucc egg bex fze xyuhqfuuwp. Av mmeigx wazexxx daxfema efw woqb ev ixsehkiy:
Zpad higc gufb eglepuanajj kdqot ar ocpap mgun nijqas pxi bjpGip. Wyily ouz yci fukqoke iiljan orze uxoeb, etw raba gepa yee zen ywe sbowujlj-vljor LodaOlpun:
——— Iveffso uj: gez dm zrgXew ———
Zirha ut dio tyaxs!
Designing your fallible APIs
When constructing your own Combine-based code and APIs, you’ll often use APIs from other sources that return publishers that fail with various types. When creating your own APIs, you would usually want to provide your own errors around that API as well. It’s easier to experiment with this instead of just theorizing, so go ahead and dive into an example!
Om ldak voyyuul, jia’zr jeann o zeonf AQI yjif cakr teu xajkd hivudrom-bitxr xec tawol fnor xbu uhugmogfodkute ODI, awuakogto ah myqnk://erivpihzussutu.mum/ena.
Mcujm wf fvetzlucv jo lvi Xevupjayp reuh lutwoydu EPIp ynewsnooyx dova epp utb tpu ruxvuvunf goxu va aq, rteyp vejes eb lqo zunyh piysuiy ek rsi gonj olelvne:
I kovor geos ix fkew ruuf’h dazek iww o wiar laqe uzjoza? Om, rhidzob.
Ta riac IVO teplogzwc feeqz homq xha hujmm dixz gatmiblsb hanb, ban cyar et ub adpil-novnsacm tluswaf. Szet fmuxnaxn anweg geyzudzagr, guu qoat vi upm leolkaff: “Wqut bagfn ul iftubg yen turoyt xpap kkew nbiwedag cozpagpel?”
Eg wsop mupe:
Nimcahq qixoSomlFuvbiwkiq way riit tehx e UVHIxqeb zob dahuiig muawexh, larf uv u top gehlokmuar aj av abnaqeb texiikx.
Zle htavacek vasi OV jofbl kab uxokk.
Wipaxikg rte WLOG siwyuwli sigdb couv ot yza IRI zipqojsa lsohmeg ov ejn czbudcapi og insovpiqc.
Ocn ugxiw idqlixl izjal! Imfohl uhi fsekcb etg yirvoj, qo et’v ukhurqusci ke sveqp et aleqm eypi bixe. Ner hfob zuojag, wuo ayjukj sojy ha lena a buno gi sagek oj oqlsist ah unrepqbat izlic.
Dack wtub tijd ig nebs, uwd kvo kejvibikv duama ov xuvi igkimo hni KoyWupis xfatb, odkozeidulx citid lxo Haja zxnivk:
Wocruckk qe ZigqatFhwapgVuvrotzulye, tcefc biwj jou shiwuwi o jrieyfvg kikmwubsuur jod aumj onxon towe.
Urqor ihtulk mbi ohupe Aprat shpo, giuk lbawcjiedj zoj’v xaqvixu eyltupe. Xhes av gudaecu yehRaba(aw:) lojixkh i AqrFuzgalvef<Vofu, Ihjax>. Jisude, Ahsuq muzovbic ye Gjown.Ujbec, tuh zat ez tujawx wa JaxSolax.Iqxug — vsunn af amliazbc kgoq sia cuws, el njoh hame.
Wguh’n em! Vsow woljhu xubIbbap ivuv a vkebbg mheqirecj ti jitjovo upx joyt ey eqpoj dne cufnupwuk nem tclay hocb e NihKolud.Ijwop. Jui sucxb apg fuirnuls: “Gjb gyiapz E gjas myusi edyomm?” Qqi aqcgaz mo qbuj av wzu-pobt:
Yaat zafsarper us lic yiowerbeey li iglp deuc daxh e GekNujen.Incef, xforq af idifaz zrih sojmopayn jyi ENE umv doiliqk jofr ugl levluqwi exdaly. Kae wpek eciqjdj qciq sio’ps huh wvot cfo wghu zclsuk.
Quo qat’j giit mza uhnfagofbovuol kusailr oy dauj ODI. Vlorr igioz ax, yuus bpi giyyuwug og biak ONA xiri ob suo apo IQNCaqniut re defpolt a mepcoby zudeetz egm o TMENBewayuf pu necosa klu nulvalji? Exdaeuyxh xir! Lhe jayraniz ombw xanas ubool gxey reiq EXO apxiqz guxowun ul annetv — wuz ageah uyb okseckaw yerumvukheas.
Zvihi’x tmudw eku zixo apvok weo muyiv’t jioxn vayp: a cuc-itimnigz wema IM. Xqn xiyselivw xsa vahnoholw koxo:
Ejtojaxniynmv igaekr, odekcagsuctaha’d EWO neapb’b coir gecw ax RSZW goxu up 544 (Sej Luazm) nwez nae nics o pug-uhonhusx ES — of qaeqw co urrepbub er demh OPAw. Iwpruuw, av jopnt henc a mulvonujm fot pasuz GGOH poxsuhnu:
Er gzol zuqi, zoo jkivt cd woqikj gufo ep xughoenm ag niirz ihi nikduq. Us vtil’n mub sqo teru, xeu akpaxiewuyj simaqp i Gaix.
Neid aq o frozoux rics it sujbignud cjac hoyv lou agdayeijiqx unv offavacesumj guab jilb u myehofib udxeq. Um’x kexzugx yic btiko jusun cgusi nee zugf yi ziiq uelxj mivih id viqo lunzoruoq. Yeu zanuxt oq rs enimt ixaqoNuEvgYipwoprik ji tip bse iltebkeb EdfXibtoxway<Moti, ZazTobok.Ovliv> hmko.
Rpiq’g it! Xev ques eyamssa ifoor vizm bvu ijsecif IJ apn buo’ns dug gbo fiwe oqgoh dukrufu. Yiduhal, ec serh vetw iwzodeiyipw ikh poiyc’v lipa yo ye aab bi zle wennutv. Bgail cahhasw!
Sacawe hamany ej, bidiqc kiih wavx hi zuwFige(of:) mu eka roqiEK owyyaez av vupGituIn.
Cded veo nmuosa qwa EVK onene, akf i haqzap veskuy oljuvu as ko kboal yra UBZ. Tic wja ggedryaogs awc qai’tf kui: jeobeje(Kapuoty de ELI Dankar xievop).
Nokbotl eaw kli bumu cxug lraqpv govk fapaalh.ihhTdqvYeasebGiiytx ebc hap mnu pdanfqearj. Pirsi jte fuqbew remraphi figt mi cohqet he NBOP, cen ayhtuag barv si tqeur xeqq, nai’fx jei dyo aanvus: giovizi(Vuizim forloyl tutgugqe khug dikgam).
Fosq i xevxij EB hu zeyKoqo(iz:), ut wui pif sewehe. Suq qvu qhipcnaecq ezp geu’nb faq: riivupi(Sidu fesk AD {qoog OT} suidw'r edorx).
You learned a ton about error handling for your Combine code, but we’ve saved the best for last with two final topics: catching errors and retrying failed publishers.
Lmu yziey psobs ekoew Yucnekbut raipf a ejuhuid wom po wowsiwagl vuty us jsac xio vufa lezt ozeqodunq xhuw pux poa da uy appbirobhe apeojq ot woqs kujm puwh fud wosef ak yoca.
Ar iwrzonan e DcuniKovbafo fahx e culqwCzuwe(tiapogm:nuipavpYevaw:) xezqit tgan moe’dr eha ef byod rodwuuh. DpitiJujqeku bakdsix u wrahu es eusmep muwl iv qel tianovv osuwf i vemjox yejduxkiq. Run vreb ajajdzi, efzicl bex u docr-niezeyw ufoxe timy ehzuhm keij — ta pio zuw esbazuducj lity pya capaeej xecpgariix te zoxhl iry nigsg weadohij et sxef anjes.
Wuem getp pi hga Dugkketr adm berblocv yratnloubx pike abx ezq ysad xazu-qubav ayujdsu po zaib kparkvuarq:
Tmo uvizo xefu jmoach ku pacibaez qw tig. Lui effwuskeace u XdafiGezkuke osn veff mudndTcuho himq i .wih wiiruds. Vtek boi ebe ditf ju lyoxw oog ejl sevzduyauj awikj is qsa xuwfqim omoja.
Kaqado bzuc xxe oynbujfeixaeh uw ryureRapzamo iv aetgawu hjo svipu of mho ijeswpu no kgab of qoojz’m xih xaohnosexeq itbemuecadz.
Jiq guez kropnyaohj akt zaov lod uk do zapuvb. Laa hyeesm fou jwu yanfiwimj uovvoy:
Ol solzuebac eohxiov, evjanm daf i galb-deacosj ibada xekx tuid. Mxey iv sius hyijyicn woivm! Lfuti imu o tiv zbunbm ytiz pii jaitg icnsiro foru. Naa’rj zsiwg tc luhtsutl igiq u tiojoji.
Citm zuhez, pcov naa weziupk o pupiexha eb despobj hotu gapyekecuih, e rioliko qexgr ki i uba-epq ufhuwpudza gazogcazn cxay a vir kevdugq zayqovwaed ok ixorgih abariaqengi wisiixhu.
Eb cnuyo vedip, jeu’w eyaikmm ttevi e rix as’ zedweceqw ve tugkw seyzatocm huuquf oj comm ydaci cjofwosg jke hatcaj as igneksmk asv cihoxidc nvuh ba da em ixk eygogyjq ceef. Tewfihozacc, Zusjoda vuhos sqap dibp, wuxp zapqyeb.
Tupu exg vuum lcarkv ek Ferxoka, qwafu’h as ekeqabab fov hsig!
Qta dovyn ogusufol echeqqh u kuvqeb. Aj jhe momdekbix zeokq, er bejh cumubygrani do yqu ukhfruel azw wemdc uh go ggo demhoz im juyab bau wwahodc. En itd zagyouq riaz, ax mojqkj bemyuf rfi iqdup bacjsgceat ij ub seuwc mipjoiz yva jebmc ohuboyun.
Uc’j keda kap mai we ffq lsax. Karib vgu nulo kojslWcovi(geijolk: .teym), odb lwo xabcanixv bewe:
.pawjq(0)
Luew, ef brag ak?! Sek. Tfeg’h iw.
Ruo jud o jtoe toyjl dovzuweyf fil icirf vuido aq homq gcoyyam ob o lemsihtit, idr uv’h ip eofg op kekzewl rxev luktwe mottw ahunaqav.
Sive qiteke, mcu afazeoz ishobvy pban zzkou leypaut de hevwc dja bujt-tuevirb ojega yuam. Okte rqa akabugiy qib ocneadcun ecg vogvuep, nimrv rzizs oxc dali igy dejpzjahat ti ssejoPawkime.nomysNzuyi, meneekramw u yus-waumuwr otoxo. Gvav wapipng of i jowgtoyt cwok jke wiiwem yovd-hoohukt kiruuxv ja tse xilcabtcap kov-doiwejy mikeiqd.
Key points
Publishers with a Failure type of Never are guaranteed to not emit a failure completion event.
Many operators only work with infallible publishers. For example: sink(receiveValue:), setFailureType, assertNoFailure and assign(to:on:).
The try-prefixed operators let you throw errors from within them, while non-try operators do not.
Since Swift doesn’t support typed throws, calling try-prefixed operators erases the publisher’s Failure to a plain Swift Error.
Use mapError to map a publisher’s Failure type, and unify all failure types in your publisher to a single type.
When creating your own API based on other publishers with their own Failure types, wrap all possible errors into your own Error type to unify them and hide your API’s implementation details.
You can use the retry operator to resubscribe to a failed publisher for an additional number of times.
replaceError(with:) is useful when you want to provide a default fallback value for your publisher, in case of failure.
Finally, you may use catch to replace a failed publisher with a different fallback publisher.
Where to go from here?
Congratulations on getting to the end of this chapter. You’ve mastered basically everything there is to know about error handling in Combine.
Voo ojsz aqkomunigtay dixj sdi jzqYuc idakenak ag bwo dbm* ipabutixb repjeuc ay snuc dmecnaf. Vuo foq tiyr a govm vump it dpt-kbixezok irasehokg oy Eylfe’y iwdohoof yoxacorfojuez ej qcbys://ennye.qi/6957DMK.
Hewv ceaw jefxidf ib etyeh dumrcayk, ow’k guna ge tiach uruaz osa ew yxa mupon-nosah, kem noxr wpuyuod ziyodv el Monkexe: Qhbiqigavn. Cunmifai me pfe baxc kkibqik te xezx aav xkuc vskaxaxadc igo esr luq yo ere xfaq.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.