Purpose
This include file provides a value-or-error return type for MQL5, so functions can report success or failure explicitly instead of through the global GetLastError() / ResetLastError() state — which is easy to forget, easy to overwrite, and forces out-parameters and "magic" return values.
What it does
A function returns one object that either holds a value or an Error; the caller must check before using the value.
- ResultValue
— for value types (numbers, structs). - Result
— the same contract for objects held by pointer (classes). - Error — a lightweight struct (code + description); codes map to readable names via EnumToString.
- MQLError — a thin wrapper over GetLastError / ResetLastError / SetUserError.
- Macros — TRY , RETURN_ON_ERROR , PRINT_ON_ERROR , RETURN_SAME_ON_ERROR , RESULT_ON_ERROR — for early-return propagation without boilerplate.
- Optional callbacks — Then , Match , MapError (they take top-level or static functions; MQL5 has no closures).
Accessors: Value() , ValueOr(fallback) , CurrentError() , IsError() .
Usage
// Stage functions (top-level — MQL5 has no closures)
ResultValue<double> EnsurePositive(const double &value)
{
if (value <= 0.0)
{
return ResultValue<double>::Fail("price must be positive");
}
return ResultValue<double>::Ok(value);
}
ResultValue<double> ToPips(const double &price)
{
return ResultValue<double>::Ok(price / _Point);
}
Error Describe(const Error &error)
{
return Error::Create(error.code, "pipeline failed: " + error.description);
}
void OnOk(const double &value) { PrintFormat("[pipeline] result = %.1f pips", value); }
void OnFail(const Error &error) { PrintFormat("[pipeline] %s", error.description); }
// The pipeline: read -> validate -> transform -> (annotate error) -> handle
void RunPipeline()
{
SymbolDouble("EURUSD", SYMBOL_BID)
.Then(EnsurePositive)
.Then(ToPips)
.MapError(Describe)
.Match(OnOk, OnFail);
}