Report input problems with labels instead of throwing.

validation-status Defensive code can return a status label for bad input rather than throwing an exception. A safe default keeps later steps deterministic.

Validation Status

age
ValidationStatus.scala
Replay: real traced execution (multi-file project)
object Main {
  def main(args: Array[String]): Unit = {
    val age = 25
    var status = "ok"
    if (age < 0) {
      status = "invalid"
    }
    if (age > 150) {
      status = "too-large"
    }
    val safeAge = if (status == "ok") age else 0

    println("age=" + age)
    println("status=" + status)
    println("safeAge=" + safeAge)
  }
}
object Main {
  def main(args: Array[String]): Unit = {
    val age = -1
    var status = "ok"
    if (age < 0) {
      status = "invalid"
    }
    if (age > 150) {
      status = "too-large"
    }
    val safeAge = if (status == "ok") age else 0

    println("age=" + age)
    println("status=" + status)
    println("safeAge=" + safeAge)
  }
}
object Main {
  def main(args: Array[String]): Unit = {
    val age = 200
    var status = "ok"
    if (age < 0) {
      status = "invalid"
    }
    if (age > 150) {
      status = "too-large"
    }
    val safeAge = if (status == "ok") age else 0

    println("age=" + age)
    println("status=" + status)
    println("safeAge=" + safeAge)
  }
}
  1. age ← 25, status ← ok, safeAge ← 25

    1object Main {2  def main(args: Array[String]): Unit = {3    val age→ 25 = 25 //@age=-1, 2004    var status→ ok = "ok"5    if (age < 0) {6      status = "invalid"7    }8    if (age > 150) {9      status = "too-large"10    }11    val safeAge→ 25 = if (statusok == "ok") age25 else 01213    println("age=" + age25)14    println("status=" + statusok)15    println("safeAge=" + safeAge25)16  }17}
    outputage=25
    status=ok
    safeAge=25
  1. age ← -1, status ← ok

    1object Main {2  def main(args: Array[String]): Unit = {3    val age→ -1 = -14    var status→ ok = "ok"5    if (age < 0) {6      status = "invalid"
  2. status ← invalid

    4var status = "ok"5if (age-1 < 0) {6  status→ invalid = "invalid"7}8if (age > 150) {
  3. safeAge ← 0

    10    }11    val safeAge→ 0 = if (statusinvalid == "ok") age-1 else 01213    println("age=" + age-1)14    println("status=" + statusinvalid)15    println("safeAge=" + safeAge0)16  }17}
    outputage=-1
    status=invalid
    safeAge=0
  1. age ← 200, status ← ok

    1object Main {2  def main(args: Array[String]): Unit = {3    val age→ 200 = 2004    var status→ ok = "ok"5    if (age < 0) {6      status = "invalid"
  2. status ← too-large

    7}8if (age200 > 150) {9  status→ too-large = "too-large"10}11val safeAge = if (status == "ok") age else 0
  3. safeAge ← 0

    10    }11    val safeAge→ 0 = if (statustoo-large == "ok") age200 else 01213    println("age=" + age200)14    println("status=" + statustoo-large)15    println("safeAge=" + safeAge0)16  }17}
    outputage=200
    status=too-large
    safeAge=0