{
  "filename": "src/main/kotlin/example/OrderLookup.kt",
  "rule": "- name: coroutine-cancellation-rethrown\n  where: \"src/main/kotlin/example/OrderLookup.kt\"\n  ensure: >-\n    A caught CancellationException must be rethrown, not turned into a successful fallback value.",
  "corrected": "package example\nimport kotlinx.coroutines.CancellationException\n\nsuspend fun <T> loadOrder(read: suspend () -> T, fallback: () -> T): T {\n    return try {\n        read()\n    } catch (cancelled: CancellationException) {\n        throw cancelled\n    } catch (failure: Exception) {\n        fallback()\n    }\n}\n",
  "broken": "package example\nimport kotlinx.coroutines.CancellationException\n\nsuspend fun <T> loadOrder(read: suspend () -> T, fallback: () -> T): T {\n    return try {\n        read()\n    } catch (cancelled: CancellationException) {\n        fallback()\n    } catch (failure: Exception) {\n        fallback()\n    }\n}\n",
  "regression": [
    "        throw cancelled",
    "        fallback()"
  ],
  "test_scenarios": [
    [
      "Read succeeds",
      "Original value"
    ],
    [
      "Ordinary read failure",
      "Explicit fallback"
    ],
    [
      "Parent coroutine cancels",
      "CancellationException propagates"
    ],
    [
      "Blocking driver ignores cancellation",
      "Timeout and dispatcher test documents the limitation"
    ]
  ],
  "test_source": "import kotlinx.coroutines.CancellationException\nimport kotlinx.coroutines.test.runTest\nimport kotlin.test.Test\nimport kotlin.test.assertFailsWith\n\nclass OrderLookupTest {\n    @Test fun cancellationDoesNotBecomeFallback() = runTest {\n        assertFailsWith<CancellationException> {\n            loadOrder<Int>({ throw CancellationException(\"stop\") }, { 0 })\n        }\n    }\n}",
  "test_command": "./gradlew test --tests example.OrderLookupTest"
}