How it works
A catch clause can include a when filter to describe the failures a particular handler understands. The sample handles a FormatException only when the current input is the known invalid token. The valid token parses to twelve, and the invalid token produces the explanatory output instead of terminating the loop.
The exception type already narrows the contract. A malformed number and a value outside the integer range are different failures. int.Parse can report overflow separately from a formatting problem. This handler does not pretend that every failure means the same thing, which keeps unexpected conditions observable during development.
A filter is evaluated as part of deciding which handler should run. Keep it simple and avoid side effects such as changing application state. A filter that logs, mutates counters, or calls another unreliable operation can make the error path harder to predict than the original calculation. Diagnostic selection should remain easy to inspect.
For ordinary user-supplied numbers, TryParse is often the clearer API because invalid text is an expected outcome rather than an exceptional control path. This lesson uses Parse to show exception filtering. Selecting the right parsing API is a separate design decision from selecting which exceptional failures a catch clause handles.
Practice by adding a very large numeric string and observing the exception type. Add a separate OverflowException handler with a distinct message. Then replace the parsing loop with TryParse and compare the resulting control flow. Keep invalid text and out-of-range numeric input distinguishable if the user needs different guidance.
Finally, avoid catch-and-continue behavior that discards the input identity or substitutes a valid-looking number. An import pipeline should report which record failed and why. The useful question is whether a handler can actually recover while preserving the program's invariants; if it cannot, propagating an informative failure is better than concealing it.
A working example
using System;
using System.Linq;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
using System.Runtime.CompilerServices;
foreach (string value in new[] { "12", "bad" }) {
try { Console.WriteLine(int.Parse(value, CultureInfo.InvariantCulture)); }
catch (FormatException) when (value == "bad") { Console.WriteLine("invalid input"); }
}
Expected output
12 invalid input
A catch filter adds a condition without catching every exception type.