{"id":1477,"date":"2026-11-03T18:00:00","date_gmt":"2026-11-03T18:00:00","guid":{"rendered":"https:\/\/wade.one\/blog\/?p=1477"},"modified":"2026-11-03T18:00:00","modified_gmt":"2026-11-03T18:00:00","slug":"kotlin-cancellation-should-survive-your-error-handling","status":"publish","type":"post","link":"https:\/\/wade.one\/blog\/2026\/11\/03\/kotlin-cancellation-should-survive-your-error-handling\/","title":{"rendered":"Kotlin Cancellation Should Survive Your Error Handling"},"content":{"rendered":"<p>Catching every exception around a coroutine can accidentally turn cancellation into an ordinary application failure. A screen closes, the job is cancelled, and a broad catch block decides to display an error or try again. The code is being helpful about work that was supposed to stop.<\/p>\n<p>Kotlin&#8217;s <a href=\"https:\/\/kotlinlang.org\/docs\/coroutines-cancellation.html\">cancellation guide<\/a> explains that cancellation is cooperative and uses CancellationException. If you catch that exception while handling other failures, rethrow it so cancellation can continue through the coroutine machinery. The surrounding scope and the work inside it both need to participate.<\/p>\n<p>For me, a useful check is to cancel the operation at a realistic point and observe what follows. Does the child work finish, are resources released, and does the closed screen stay closed? Testing only the successful return value leaves out the behaviour that matters when someone navigates away halfway through.<\/p>\n<p>This does not need a complicated exception hierarchy. It needs error handling that distinguishes an operation failing from its owner no longer wanting it. Make that distinction visible, keep cleanup reliable, and resist turning every interrupted job into a fresh attempt. Sometimes the correct outcome is simply that the work stops.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Catching every exception around a coroutine can accidentally turn cancellation into an ordinary application failure.<\/p>\n","protected":false},"author":0,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[13],"tags":[308,77,75],"class_list":["post-1477","post","type-post","status-publish","format-standard","hentry","category-programming","tag-cancellation","tag-coroutines","tag-kotlin"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.8 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Kotlin Cancellation Should Survive Your Error Handling - wade.one<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/wade.one\/blog\/2026\/11\/03\/kotlin-cancellation-should-survive-your-error-handling\/\" \/>\n<meta property=\"og:locale\" content=\"en_GB\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Kotlin Cancellation Should Survive Your Error Handling - wade.one\" \/>\n<meta property=\"og:description\" content=\"Catching every exception around a coroutine can accidentally turn cancellation into an ordinary application failure.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/wade.one\/blog\/2026\/11\/03\/kotlin-cancellation-should-survive-your-error-handling\/\" \/>\n<meta property=\"og:site_name\" content=\"wade.one\" \/>\n<meta property=\"article:published_time\" content=\"2026-11-03T18:00:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/wade.one\/blog\/wp-content\/uploads\/2015\/02\/Wade-Logo-cropped.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1518\" \/>\n\t<meta property=\"og:image:height\" content=\"1506\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@wadewomersley\" \/>\n<meta name=\"twitter:site\" content=\"@wadewomersley\" \/>\n<meta name=\"twitter:label1\" content=\"Estimated reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"1 minute\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/2026\\\/11\\\/03\\\/kotlin-cancellation-should-survive-your-error-handling\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/2026\\\/11\\\/03\\\/kotlin-cancellation-should-survive-your-error-handling\\\/\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"Kotlin Cancellation Should Survive Your Error Handling\",\"datePublished\":\"2026-11-03T18:00:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/2026\\\/11\\\/03\\\/kotlin-cancellation-should-survive-your-error-handling\\\/\"},\"wordCount\":199,\"publisher\":{\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/#\\\/schema\\\/person\\\/8b4739f8f8bb2cff5d792d4b8779fcc3\"},\"keywords\":[\"cancellation\",\"coroutines\",\"kotlin\"],\"articleSection\":[\"Programming\"],\"inLanguage\":\"en-GB\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/2026\\\/11\\\/03\\\/kotlin-cancellation-should-survive-your-error-handling\\\/\",\"url\":\"https:\\\/\\\/wade.one\\\/blog\\\/2026\\\/11\\\/03\\\/kotlin-cancellation-should-survive-your-error-handling\\\/\",\"name\":\"Kotlin Cancellation Should Survive Your Error Handling - wade.one\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/#website\"},\"datePublished\":\"2026-11-03T18:00:00+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/2026\\\/11\\\/03\\\/kotlin-cancellation-should-survive-your-error-handling\\\/#breadcrumb\"},\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/wade.one\\\/blog\\\/2026\\\/11\\\/03\\\/kotlin-cancellation-should-survive-your-error-handling\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/2026\\\/11\\\/03\\\/kotlin-cancellation-should-survive-your-error-handling\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/wade.one\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Kotlin Cancellation Should Survive Your Error Handling\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/wade.one\\\/blog\\\/\",\"name\":\"wade.one\",\"description\":\"wade womersley - york based software engineer\",\"publisher\":{\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/#\\\/schema\\\/person\\\/8b4739f8f8bb2cff5d792d4b8779fcc3\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/wade.one\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-GB\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/#\\\/schema\\\/person\\\/8b4739f8f8bb2cff5d792d4b8779fcc3\",\"name\":\"Wade Womersley\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/wp-content\\\/uploads\\\/2015\\\/02\\\/200px.png\",\"url\":\"https:\\\/\\\/wade.one\\\/blog\\\/wp-content\\\/uploads\\\/2015\\\/02\\\/200px.png\",\"contentUrl\":\"https:\\\/\\\/wade.one\\\/blog\\\/wp-content\\\/uploads\\\/2015\\\/02\\\/200px.png\",\"width\":202,\"height\":200,\"caption\":\"Wade Womersley\"},\"logo\":{\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/wp-content\\\/uploads\\\/2015\\\/02\\\/200px.png\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Kotlin Cancellation Should Survive Your Error Handling - wade.one","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/wade.one\/blog\/2026\/11\/03\/kotlin-cancellation-should-survive-your-error-handling\/","og_locale":"en_GB","og_type":"article","og_title":"Kotlin Cancellation Should Survive Your Error Handling - wade.one","og_description":"Catching every exception around a coroutine can accidentally turn cancellation into an ordinary application failure.","og_url":"https:\/\/wade.one\/blog\/2026\/11\/03\/kotlin-cancellation-should-survive-your-error-handling\/","og_site_name":"wade.one","article_published_time":"2026-11-03T18:00:00+00:00","og_image":[{"width":1518,"height":1506,"url":"https:\/\/wade.one\/blog\/wp-content\/uploads\/2015\/02\/Wade-Logo-cropped.png","type":"image\/png"}],"twitter_card":"summary_large_image","twitter_creator":"@wadewomersley","twitter_site":"@wadewomersley","twitter_misc":{"Estimated reading time":"1 minute"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/wade.one\/blog\/2026\/11\/03\/kotlin-cancellation-should-survive-your-error-handling\/#article","isPartOf":{"@id":"https:\/\/wade.one\/blog\/2026\/11\/03\/kotlin-cancellation-should-survive-your-error-handling\/"},"author":{"name":"","@id":""},"headline":"Kotlin Cancellation Should Survive Your Error Handling","datePublished":"2026-11-03T18:00:00+00:00","mainEntityOfPage":{"@id":"https:\/\/wade.one\/blog\/2026\/11\/03\/kotlin-cancellation-should-survive-your-error-handling\/"},"wordCount":199,"publisher":{"@id":"https:\/\/wade.one\/blog\/#\/schema\/person\/8b4739f8f8bb2cff5d792d4b8779fcc3"},"keywords":["cancellation","coroutines","kotlin"],"articleSection":["Programming"],"inLanguage":"en-GB"},{"@type":"WebPage","@id":"https:\/\/wade.one\/blog\/2026\/11\/03\/kotlin-cancellation-should-survive-your-error-handling\/","url":"https:\/\/wade.one\/blog\/2026\/11\/03\/kotlin-cancellation-should-survive-your-error-handling\/","name":"Kotlin Cancellation Should Survive Your Error Handling - wade.one","isPartOf":{"@id":"https:\/\/wade.one\/blog\/#website"},"datePublished":"2026-11-03T18:00:00+00:00","breadcrumb":{"@id":"https:\/\/wade.one\/blog\/2026\/11\/03\/kotlin-cancellation-should-survive-your-error-handling\/#breadcrumb"},"inLanguage":"en-GB","potentialAction":[{"@type":"ReadAction","target":["https:\/\/wade.one\/blog\/2026\/11\/03\/kotlin-cancellation-should-survive-your-error-handling\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/wade.one\/blog\/2026\/11\/03\/kotlin-cancellation-should-survive-your-error-handling\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/wade.one\/blog\/"},{"@type":"ListItem","position":2,"name":"Kotlin Cancellation Should Survive Your Error Handling"}]},{"@type":"WebSite","@id":"https:\/\/wade.one\/blog\/#website","url":"https:\/\/wade.one\/blog\/","name":"wade.one","description":"wade womersley - york based software engineer","publisher":{"@id":"https:\/\/wade.one\/blog\/#\/schema\/person\/8b4739f8f8bb2cff5d792d4b8779fcc3"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/wade.one\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-GB"},{"@type":["Person","Organization"],"@id":"https:\/\/wade.one\/blog\/#\/schema\/person\/8b4739f8f8bb2cff5d792d4b8779fcc3","name":"Wade Womersley","image":{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/wade.one\/blog\/wp-content\/uploads\/2015\/02\/200px.png","url":"https:\/\/wade.one\/blog\/wp-content\/uploads\/2015\/02\/200px.png","contentUrl":"https:\/\/wade.one\/blog\/wp-content\/uploads\/2015\/02\/200px.png","width":202,"height":200,"caption":"Wade Womersley"},"logo":{"@id":"https:\/\/wade.one\/blog\/wp-content\/uploads\/2015\/02\/200px.png"}}]}},"jetpack_publicize_connections":[],"jetpack_sharing_enabled":true,"jetpack-related-posts":[{"id":1182,"url":"https:\/\/wade.one\/blog\/2026\/04\/14\/why-kotlin-coroutines-are-worth-the-learning-curve\/","url_meta":{"origin":1477,"position":0},"title":"Why Kotlin Coroutines Are Worth the Learning Curve","author":"","date":"April 14, 2026","format":false,"excerpt":"Kotlin coroutines are worth learning because they make async code easier to read and easier to reason about. They still need discipline, but they usually beat callback-shaped code by a long way.","rel":"","context":"In &quot;Programming&quot;","block_context":{"text":"Programming","link":"https:\/\/wade.one\/blog\/category\/programming\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1175,"url":"https:\/\/wade.one\/blog\/2026\/04\/07\/what-good-kotlin-code-feels-like-after-too-much-java\/","url_meta":{"origin":1477,"position":1},"title":"What Good Kotlin Code Feels Like After Too Much Java","author":"","date":"April 7, 2026","format":false,"excerpt":"Kotlin feels good when it removes friction instead of adding ceremony. After enough Java, that difference becomes obvious very quickly.","rel":"","context":"In &quot;Programming&quot;","block_context":{"text":"Programming","link":"https:\/\/wade.one\/blog\/category\/programming\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1343,"url":"https:\/\/wade.one\/blog\/2026\/06\/10\/jetpack-compose-1-11-testing-changes-deserve-attention\/","url_meta":{"origin":1477,"position":2},"title":"Jetpack Compose 1.11 Testing Changes Deserve Attention","author":"Wade","date":"June 10, 2026","format":false,"excerpt":"Jetpack Compose 1.11's testing changes are worth planning for because timing assumptions can quietly break mobile test suites.","rel":"","context":"In &quot;Programming&quot;","block_context":{"text":"Programming","link":"https:\/\/wade.one\/blog\/category\/programming\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1308,"url":"https:\/\/wade.one\/blog\/2026\/05\/20\/android-studio-local-ai-agents-are-the-interesting-bit\/","url_meta":{"origin":1477,"position":3},"title":"Android Studio Local AI Agents Are the Interesting Bit","author":"Wade","date":"May 20, 2026","format":false,"excerpt":"Android Studio's Gemma 4 support is interesting because it moves agentic coding toward local, Android-specific workflows.","rel":"","context":"In &quot;AI&quot;","block_context":{"text":"AI","link":"https:\/\/wade.one\/blog\/category\/ai\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1333,"url":"https:\/\/wade.one\/blog\/2026\/06\/01\/codex-on-mobile-changes-the-shape-of-background-coding\/","url_meta":{"origin":1477,"position":4},"title":"Codex on Mobile Changes the Shape of Background Coding","author":"Wade","date":"June 1, 2026","format":false,"excerpt":"Codex on mobile is less about writing code on a phone and more about supervising background engineering work away from the desk.","rel":"","context":"In &quot;AI&quot;","block_context":{"text":"AI","link":"https:\/\/wade.one\/blog\/category\/ai\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1012,"url":"https:\/\/wade.one\/blog\/2016\/04\/15\/canada-legalises-assisted-suicide\/","url_meta":{"origin":1477,"position":5},"title":"Canada Legalises Assisted Suicide","author":"Wade","date":"April 15, 2016","format":false,"excerpt":"In what will surely spark controversy and complaints around the world, Canada has just become the latest country to allow assisted suicide from a doctor for those who are terminally ill or in severe pain and will be for the rest of their lives. On Thursday, 14th April, 2016, Justin\u2026","rel":"","context":"In &quot;News&quot;","block_context":{"text":"News","link":"https:\/\/wade.one\/blog\/category\/news\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/wade.one\/blog\/wp-content\/uploads\/2016\/04\/220px-Justin_Trudeau_APEC_2015.jpg?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]}],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/posts\/1477","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/comments?post=1477"}],"version-history":[{"count":1,"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/posts\/1477\/revisions"}],"predecessor-version":[{"id":1491,"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/posts\/1477\/revisions\/1491"}],"wp:attachment":[{"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/media?parent=1477"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/categories?post=1477"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/tags?post=1477"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}