A record can model success or failure without throwing, keeping the caller on one explicit path.

Program

Play the program to parse a valid port, then select an out-of-range value.

text
result_record.dart
Replay: real traced execution (multi-file project)
({bool ok, int value}) parsePort(String text) {
  var parsed = int.tryParse(text);
  if (parsed == null) return (ok: false, value: 0);
  if (parsed < 1 || parsed > 65535) return (ok: false, value: 0);
  return (ok: true, value: parsed);
}

void main() {
  var text = '8080';
  var result = parsePort(text);
  print('${result.ok}:${result.value}');
}
({bool ok, int value}) parsePort(String text) {
  var parsed = int.tryParse(text);
  if (parsed == null) return (ok: false, value: 0);
  if (parsed < 1 || parsed > 65535) return (ok: false, value: 0);
  return (ok: true, value: parsed);
}

void main() {
  var text = '70000';
  var result = parsePort(text);
  print('${result.ok}:${result.value}');
}
  1. text ← 8080

    8void main() {9  var text = '8080';10  var result = parsePort(text);
    values this step8080text
  2. call ← parsePort('8080')

    9var text = '8080';10var result = parsePort(text);11print('${result.ok}:${result.value}');
    values this stepparsePort('8080')call8080text
  3. parsed ← 8080

    1({bool ok, int value}) parsePort(String text) {2  var parsed = int.tryParse(text);3  if (parsed == null) return (ok: false, value: 0);
    values this step8080parsed8080text
  4. in range ← true

    3if (parsed == null) return (ok: false, value: 0);4if (parsed < 1 || parsed > 65535) return (ok: false, value: 0);5return (ok: true, value: parsed);
    values this steptruein range8080parsed
  5. return value ← (ok: true, value: 8080)

    4  if (parsed < 1 || parsed > 65535) return (ok: false, value: 0);5  return (ok: true, value: parsed);6}
    values this step(ok: true, value: 8080)return value8080parsed
  6. result ← (ok: true, value: 8080)

    9var text = '8080';10var result = parsePort(text);11print('${result.ok}:${result.value}');
    values this step(ok: true, value: 8080)result
  7. print('${result.ok}:${result.value}');

    10  var result = parsePort(text);11  print('${result.ok}:${result.value}');12}
    outputtrue:8080
    values this step(ok: true, value: 8080)result
  1. text ← 70000

    8void main() {9  var text = '70000';10  var result = parsePort(text);
    values this step70000text
  2. call ← parsePort('70000')

    9var text = '70000';10var result = parsePort(text);11print('${result.ok}:${result.value}');
    values this stepparsePort('70000')call70000text
  3. parsed ← 70000

    1({bool ok, int value}) parsePort(String text) {2  var parsed = int.tryParse(text);3  if (parsed == null) return (ok: false, value: 0);
    values this step70000parsed70000text
  4. out of range ← true

    3if (parsed == null) return (ok: false, value: 0);4if (parsed < 1 || parsed > 65535) return (ok: false, value: 0);5return (ok: true, value: parsed);
    values this steptrueout of range70000parsed
  5. result ← (ok: false, value: 0)

    9var text = '70000';10var result = parsePort(text);11print('${result.ok}:${result.value}');
    values this step(ok: false, value: 0)result
  6. print('${result.ok}:${result.value}');

    10  var result = parsePort(text);11  print('${result.ok}:${result.value}');12}
    outputfalse:0
    values this step(ok: false, value: 0)result
named record `({bool ok, int value})` names fields on a lightweight result.
no exception Invalid data returns `ok: false` instead of throwing.
caller check The caller prints both the success flag and value.