Type/to search
Built-in Functions
Structures
Built-in Variables and Constants
Conventions
Symbols
Failures and null values
Exchanges

Failed calls return a null value

When a function of an exchange object, or most global functions, fails (network error, timeout, the exchange rejects the request, a parameter the exchange does not accept, etc.), the strategy is not stopped. Instead:

  1. an error log entry is written (it can be filtered with SetErrorFilter);
  2. the error message is kept as the last error and can be read with GetLastError;
  3. a null value is returned: null in JavaScript, None in Python, Err in Rust (carrying the error message).

A successful query with no data returns an empty array [] (for example exchange.GetOrders() with no open orders), which is different from the null value of a failure. Tell the two apart when checking results, and never treat a null value as "no data" and keep calculating. A few functions return something else on failure; the "Returns" section of each function page is authoritative (for example HttpQuery() returns an empty string on failure).

Unsupported functions

When an exchange or the runtime does not support a function or a query range, the call is treated as a failure: an "unsupported" error is recorded (error log + GetLastError()), a null value is returned and the strategy keeps running. It never returns values that look like data, such as [], {} or 0.

Programming errors throw

When the call itself is wrong (for example calling a function without symbol before any trading pair is set, or passing a parameter that cannot be parsed), JavaScript and Python throw an exception, which stops the strategy if it is not caught; Rust returns Err. Such errors need a code change; retrying does not help.

Pattern

Check for the null value before using a result; wrap calls that should be retried automatically with _C.

Examples

Distinguish a failed call (null value) from a successful query with no data (empty array).

javascript
function main() { var ticker = exchange.GetTicker("BTC_USDT") if (ticker === null) { // the call failed: the error is already logged and GetLastError() returns the reason Log("GetTicker failed:", GetLastError()) return } var orders = exchange.GetOrders("BTC_USDT") if (orders === null) { Log("GetOrders failed:", GetLastError()) } else if (orders.length === 0) { Log("no open orders") } else { Log("open orders:", orders.length) } }
python
def main(): ticker = exchange.GetTicker("BTC_USDT") if ticker is None: # the call failed: the error is already logged and GetLastError() returns the reason Log("GetTicker failed:", GetLastError()) return orders = exchange.GetOrders("BTC_USDT") if orders is None: Log("GetOrders failed:", GetLastError()) elif len(orders) == 0: Log("no open orders") else: Log("open orders:", len(orders))
rust
fn main() { let ticker = match exchange.GetTicker("BTC_USDT") { Ok(t) => t, Err(e) => { // the call failed: Err carries the error message Log!("GetTicker failed:", e); return; } }; Log!("last:", ticker.Last); match exchange.GetOrders("BTC_USDT") { Ok(orders) if orders.is_empty() => Log!("no open orders"), Ok(orders) => Log!("open orders:", orders.len()), Err(e) => Log!("GetOrders failed:", e), } }