2.4 KiB
2.4 KiB
ADR-001: Error Codes Over Exceptions
Context
Clean Code (Robert C. Martin) mandates: "Use exceptions, never return codes." This principle assumes a language with try/catch/throw semantics (Java, C++, Python). MQL5 has none of these constructs. The language provides no mechanism to throw, propagate, or catch exceptions.
The native MQL5 API itself is built entirely on error codes:
OrderSend()returnsbooland fillsMqlTradeResult.retcodeGetLastError()returns the last runtime error code- Every trade operation follows the pattern:
bool success+int error_code
Decision
Use the bool return + output parameter pattern for all fallible operations in the framework:
bool TryExecuteOrder(MqlTradeRequest &request, MqlTradeResult &result);
This mirrors the native OrderSend() contract exactly. Additionally:
- Named constants (
SYNTH_ERR_OFF_QUOTES,SYNTH_ERR_REQUOTE, etc.) replace raw integer literals to make error-handling paths self-documenting. - A guard function (
IsExecutionError()) centralizes the "what counts as failure?" logic, preventing scattered!= 0comparisons. - The method name uses
Tryprefix (TryExecuteOrder, notExecuteOrder) to signal at the call site that failure is a normal, expected outcome — not an exceptional case.
Consequences
Positive
- Zero friction for MQL5 developers: the pattern matches what they already use daily with
OrderSend(). - Named constants are grep-searchable and self-documenting, capturing the spirit of Clean Code's error handling guidelines.
- Guard function prevents the bug class where a developer compares against the wrong integer value.
Negative
- Callers must always check the return value. Unlike exceptions, nothing forces the caller to handle the error. This is mitigated by the
Tryprefix convention (signals fallibility) and by the test suite (which validates both success and failure paths). - CQS violation:
TryExecuteOrder()both performs an action AND returns a result. This is unavoidable without exceptions. Splitting into separateExecuteOrder()+GetLastExecutionError()would create a fragile two-step protocol where the caller can forget step 2.
Risk
- If a future version of MQL5 adds exception support, this pattern should be reevaluated. The interface
IMarketEnvironmentwould need a new version.