Checkpoint: Gateway Failures

The Course
•
4 min read

Connect a decoder and a synchronous publisher. Receive should return a normal failure result when input is invalid, but it must let a subscriber’s programming error propagate. A broad catch around both stages would mislabel a listener defect as bad input.

Use Result<boolean>: ok:false means decoding failed; ok:true with value:false can mean a valid message reached a disposed publisher. These alternatives are not the same outcome. Narrow the ok discriminant before reading value.

This checkpoint isolates the failure boundary before the full event union is introduced into the implementation. Use a numeric decoder and injected publish function. Spend twenty minutes on all three outcomes: invalid data, a declined publish and a thrown listener error.

Predict, check, and run

Write the output before running. Use Check types first, then Check & run. Types disappear at runtime: explain both what the compiler checks and what the code actually does. Each editor is an independent ES module; await asynchronous work explicitly.

Predict, then runTypeScript
type Result<T> =
  | {
      ok: true;

      value: T;
    }
  | {
      ok: false;

      message: string;
    };

const decoded: Result<boolean> = { ok: true, value: false };

console.log(decoded.ok, decoded.value);

Enable JavaScript to edit and type-check this example.

Check your prediction
true false

Acceptance cases before you code

Write a small test plan before implementing gateway outcome distinctions. These cases extend the brief; they are not a second worked solution. Predict the expected behavior independently, then test through the public function. A good ordinary example and a good boundary example should catch different possible mistakes.

Case to tryWhat your result should demonstrate
Invalid raw inputNo publisher invocation and an expected data failure
Valid input with publisher returning falseSuccess variant contains the false result
Publisher throws an ErrorPreserve its identity instead of relabeling it as bad input

After the core task passes, deliberately break one rule and identify the case that notices it. Restore the implementation and explain the failure in terms of the contract, not the number of assertions. If a case requires a concept you have not recalled, revisit the relevant lesson before opening the solution.

Build it yourself

Exercise

Checkpoint: Gateway Failures: practise

Write receive(raw,publish) validating a finite nonnegative integer, then calling publish(count). Print false for invalid text and false for a valid count declined by publish. Assert a thrown publisher Error escapes unchanged, then print failure preserved.

Your workspaceTypeScript
// Start from the stated contract. Add a valid call and an edge case.

Enable JavaScript to edit and type-check this example.

Hint 1: the idea

Return the decoding failure before calling the collaborator.

Hint 2: a first step

Do not catch around publish; the caller must see that exception as itself.

Show one solution
One possible solutionTypeScript
type Result<T> =
  | {
      ok: true;

      value: T;
    }
  | {
      ok: false;

      message: string;
    };

function receive(
  raw: unknown,
  publish: (count: number) => boolean
): Result<boolean> {
  if (
    typeof raw !== "number" ||
    !Number.isFinite(raw) ||
    !Number.isInteger(raw) ||
    raw < 0
  ) {
    return { ok: false, message: "Invalid count" };
  }

  return { ok: true, value: publish(raw) };
}

console.log(receive("0", () => true).ok);

const declined = receive(0, () => false);

console.log(declined.ok ? declined.value : declined.message);

const failure = new Error("Subscriber defect");
let caught: unknown;

try {
  receive(0, () => {
    throw failure;
  });
} catch (error) {
  caught = error;
}

if (caught !== failure) {
  throw new Error("Failure was relabeled");
}

console.log("failure preserved");

Enable JavaScript to edit and type-check this example.

false
false
failure preserved

Trace the implementation against the task before comparing styles. A passing example supports that case; use the changes below to challenge the wider contract.

Change it and test it

Count publish calls and assert invalid input starts none. Add zero, NaN and fractional cases. Then wrap everything in a catch returning Invalid count and confirm the identity assertion catches that regression.

Was this article helpful?

Your response is saved on this device.