Five Defensive Utility Functions I Made
๐ฏ Introduction
The built-in Debug.Assert() in C# just wasn't enough. I wanted a unified system to handle assumption violations, internal bugs, and critical runtime issues that require immediate attention in a consistent way.
So, I created the following five utility functions:
global using static POCU.Core.Assertion.Check;
By declaring them globally and writing them in ALL CAPS, they stand out clearly inside logic code. Even at a glance, you can tell: "This is defensive code."
๐งฑ Common Rule
The first parameter of every function must be a bool expression.
CHECK911_THROW(user != null, "User should not be null");
- If the expression is
trueโ nothing happens. - If
falseโ the corresponding function triggers logging, alerts, or exceptions depending on its level.
In other words, you don't have to keep writing if (!condition) { ... }. A single expression clearly declares, "If this breaks, something is wrong."
๐ Function Summary
| Function | Purpose | Behavior | Ops Team Response | Exception |
|---|---|---|---|---|
| VERIFY | Observe "this should never happen" assumptions | Logs only, continues execution | Check later | โ |
| DBG_CHECK | Debug-only assertion | Stops in Debug builds only | โ | โ |
| CHECK912 | Detect internal issue (non-urgent) | Alerts + metrics tracking | Review/fix within 1โ2 days | โ |
| CHECK911 | Requires immediate attention | Alerts + metrics tracking | Immediate fix | โ |
| CHECK911_THROW | Transaction protection | Alerts + metrics tracking + throws exception | Immediate fix | โ |
๐ All CHECK functions send notifications to our company messenger, and their occurrences are automatically tracked and visualized on dashboards.
๐งฉ VERIFY โ Long-term Assumption Monitor
VERIFY is more than a simple log statement. It's a sensor for assumptions โ things you believe "should never happen," monitored over time.
VERIFY(order.TotalPrice >= 0, "Order total should never be negative");
- You believe this condition will never fail.
- But maybe, someday, once in two years, it might.
- When it does, a log arrives โ and you realize your assumption was wrong.
- If it never triggers for years, you can safely remove that line.
This is runtime validation for assumptions that can't be tested easily. It's perfect for monitoring rare edge cases or unexpected system behavior in production.
๐ก One More Trick
Sometimes you encounter old code that should never happen anymore, but you're not 100% sure it's safe to delete. In that case, do this:
// TODO(delete): delete after 2028-12-31
VERIFY(someOldFlag == false, "Old flag still being used?");
- Add a
VERIFY. - Watch it in production for a year.
- If it never triggers, safely delete the code.
This pattern works like a "live test" in production. It's like having thousands of live users running an automatic test system for free. Amazing, right? ๐ It also makes long-term code cleanup much easier to manage.
๐งช DBG_CHECK โ Debug-only Strong Assertion
DBG_CHECK(buffer.Length == expectedSize, "Unexpected buffer size");
- Executes only in Debug builds.
- Completely removed in Release builds, with zero runtime overhead.
- Enforces conditions that "must never fail during development."
โ Use
DBG_CHECKfor conditions that must break during testing.
โ UseVERIFYfor conditions you want to observe in production.
๐ CHECK912 โ Internal Issue (Non-Urgent)
CHECK912(userCache.Count > 0, "User cache is unexpectedly empty");
- Indicates a likely internal bug, but no immediate user impact.
- Sends alerts and updates metrics.
- Ops team handles it within a day or two.
Examples:
- Cache desynchronization
- Retried network failure that succeeded later
- Minor data anomalies
๐จ CHECK911 โ Critical, Requires Immediate Action
CHECK911(paymentResponse.IsValid, "Payment gateway returned invalid data");
- Used for critical situations like data loss, security issues, or direct customer impact.
- Sends instant alerts and updates metrics/dashboards.
- May also trigger operational hooks (e.g., safe mode switch).
- Does not throw exceptions, so background workers or pipelines can keep running while the ops team investigates.
๐ฃ CHECK911_THROW โ Transaction Protection
CHECK911_THROW(invoice != null, "Invoice must exist before commit");
- Behaves exactly like
CHECK911, but also throws an exception to abort the current transaction. - Prevents corrupted state from propagating to databases or external systems.
- Typically used at transaction boundaries, commit points, or right after external API calls.
Examples:
CHECK911_THROW(user != null, "User not found");
CHECK911_THROW(balance >= 0, "Negative balance detected");
Use it right before committing, or immediately after a risky side effect โ it stops the error from spreading further.
โ๏ธ Internal Mechanism Overview
All functions share the same underlying structure:
- Evaluate the
boolexpression. - If
false, call a shared logger. - The logger does the following:
- Write logs (file, console, Sentry, etc.)
- Send messenger notifications
- Update metrics for dashboards
*_THROWvariants also performthrowat the end.
In short, all of them use the same alerting infrastructure โ they just differ in severity and whether they stop execution.
๐งฉ Conclusion
All five functions serve one purpose:
"Separate logic from defense, and respond appropriately depending on when and how a problem occurs."
VERIFY: Long-term assumption monitorDBG_CHECK: Debug-only strong assertionCHECK912: Internal issue detection (non-urgent)CHECK911: Critical issue (immediate attention)CHECK911_THROW: Critical + transaction abort
And in practice, all you need in your logic code is one line:
CHECK911_THROW(totalPrice >= 0, "Negative total price detected");
That's it. Anyone reading it immediately knows: this isn't regular logic โ it's a safety line.