Throwable Not Thrown

ID

kotlin.throwable_not_thrown

Severity

low

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

Kotlin

Tags

dead-code, exception, throw

Description

Reports exception constructions whose result is never used. Constructing a Throwable subclass as a bare expression-statement is meaningless — the exception is built, immediately garbage- collected and never propagated. The most common cause is a missing throw keyword.

Rationale

// Bad — exception built and dropped, almost certainly a missing `throw`
fun guard(x: Int) {
    if (x < 0) {
        IllegalArgumentException("x must be non-negative")  // FLAW
    }
}

// OK — `throw` keyword present
fun guard(x: Int) {
    if (x < 0) {
        throw IllegalArgumentException("x must be non-negative")
    }
}

// OK — constructed exception is consumed
val ex = IllegalStateException("boom")
logger.error("failed", IllegalStateException("boom"))

The rule is conservative and only fires when the constructor call is a bare expression-statement with no consumer in the AST. Calls inside assignments, return statements, throw expressions, function arguments, or chained .message accesses are not flagged.

Remediation

  • Add the missing throw keyword if the intent was to propagate the exception.

  • Assign the constructed exception to a variable if it really is meant to be a value.

  • Pass the exception as a constructor or function argument to consume it (e.g. as a cause).