-
Notifications
You must be signed in to change notification settings - Fork 0
Error Model
Five ways a call can fail to give you an ordinary answer. Every @returns in
the library names exactly one of them, so the contract is in the annotation and
you do not have to infer it.
The arguments cannot mean anything: 31 February, nth = 0, an hour of 25, a
bounded walk that runs past its limit. This is a caller bug, and it is reported
at the call site rather than passed downstream as a value that surfaces
somewhere unrelated.
t.new_datetime(2025, 2, 31) // raises
t.nth_weekday_of_month(2025, 6, t.Weekday.FRIDAY, 0) // raises: nth = 0
The library carries 51 RAISES clauses. Every one of them has a raise behind
it.
The call is well formed and no answer exists. The fifth Friday of a month that
has four. A session window on a day the session does not run. Every parser and
every try_* form, because malformed input is data rather than a caller bug.
t.nth_weekday_of_month(2025, 6, t.Weekday.FRIDAY, 5) // na: June 2025 has four
t.parse_iso("not a date") // na
Well formed, the answer exists in the world, and the table here does not reach
it. The economic calendar and closed_for_holiday() return this.
It is a value, never na. This matters:
t.Known k = d.closed_for_holiday(t.Exchange.SSE)
bool wrong = na(k) // dead code: na(Known.UNKNOWN) is false
bool right = k == t.Known.UNKNOWN // correct
Known exists because Pine's bool cannot hold na at all. bool x = na is a
compile error, though int, enum and object types accept it. So "return na,
never false" is not expressible for a yes/no question.
The enum is also the stronger contract. UNKNOWN will not type-check anywhere a
bool is expected, so reading "not known" as "no" has to be written down, via
is_yes(), rather than happening by default.
Well formed, and the answer is no within what the library models. is_holiday,
is_trading_day, is_open, is_leap_year.
Note the qualifier. is_holiday means "closed by the published calendar", not
"nothing else can close the market".
Only when the number is a real value of the result range, never as a stand-in for "none".
This is why Session.time_to_close does not return 0 while the session runs. 0
is a real distance, so it cannot also be a flag. It returns the distance to the
next close, and na when there is none.
The clearest illustration is one function with both:
t.nth_weekday_of_month(2025, 6, t.Weekday.FRIDAY, 0) // RAISES
t.nth_weekday_of_month(2025, 6, t.Weekday.FRIDAY, 5) // na
nth = 0 is an invalid argument: there is no zeroth Friday in any month, so the
question is malformed. A fifth Friday is a valid question about a month that
happens not to contain one. Different failures, different clauses.
The date withers are the one place na and RAISE overlap, and Overflow picks
between them. A day past the end of a month clamps under CONSTRAIN and is na
under REJECT.
The time withers raise instead. There is nothing to clamp an hour of 25 to.
Several operations come in both shapes. Use the raising one for values you
constructed, and the try_ one for anything that came from outside:
| Trusted input | Untrusted input |
|---|---|
new_datetime(...) |
try_new_datetime(...) |
| direct field access |
is_valid_date(...) first |
is_valid_date is the exact predicate new_datetime enforces, so the two
cannot drift apart.
Raises name the function and the offending value:
new_session: DayMask must be in [0, 127], got -1
plus_trading_days: could not resolve 500 trading days within 1030 calendar days
next_expiry_after: ExpiryKind.VIX is a.m.-settled and has no close-shaped Hour. Use next_vix_settlement_after
A message ending "this is a library bug" means a dispatch switch met a value it does not handle. That is not something you can cause from the outside; please report it.
Previous: Value Semantics · Next: Time Zones · See also: Pitfalls
std_time v1 · API Index · Task Index · Scope and Limitations · Verification
Calendar data current to the horizons on Versioning and Data Currency. Shanghai, Bombay and Singapore answer exactly through 2026.
MPL-2.0 · Copyright (c) 2026 Jesse Sanford · published on TradingView as The_Peaceful_Lizard
Start here
The model
- Core Concepts
- Civil and Exact Arithmetic
- Value Semantics
- Error Model
- Time Zones
- Exchange Calendars
- Trading Days and Day Counts
- Expiries
- Sessions
- Formatting and Parsing
- Choosing the Right Tool
- Pitfalls
Recipes
Reference
- API Index · Task Index
- DateTime
- Session
- Zone
- Exchange
- Period · Interval
- Weekday · Enums
- Free functions
- Glossary
The fine print