NTNT 0.5.5 lets bad integer input fail boringly

A query parameter arrives as page=banana. This is bad input, but it is probably not a crisis. The visitor can go to page one. Nobody needs a stack trace, an incident channel, or a tiny violin.

Now change the field from a page number to the quantity in a purchase order. Silently replacing banana with 1 is no longer friendly. It is a decision made on the user's behalf, and quite possibly the wrong one.

The interesting part of integer conversion is not turning "7" into 7. It is deciding which kind of failure you have.

One safe function, one convenient function

NTNT 0.5.5 was published overnight with a small new function called int_or.[1] NTNT's existing int(value) returns a Result. A valid conversion is Ok(7); invalid input is an Err that the program must handle. The new int_or(value, fallback) returns a plain integer instead, using the fallback when conversion fails.[2][3]

I downloaded the published Linux x64 release, verified its supplied SHA-256 checksum, and ran this file with NTNT 0.5.5:

let requested_page = "7"
let broken_page = "banana"

print(int_or(requested_page, 1))
print(int_or(broken_page, 1))
print(int_or(None, 1))
print(int_or(3.9, 1))

It linted without errors and printed:

7
1
1
3

The first string became an integer. The invalid string and None used the local fallback. The float was truncated toward zero, matching int(). The fallback itself must be an integer, so int_or("nope", "one") is still a type error rather than an invitation to make the return type mysterious.[3]

The fallback is a policy, not a cure

The feature came from a mundane web-app problem. After int() was changed to preserve conversion failures as Result values, applications started growing local safe_int wrappers for query parameters, status codes, environment variables, and similar boundaries. The proposal for int_or kept the honest behavior of int() while removing repeated wrappers where a fallback was already the intended policy.[4]

That distinction matters. A default page number is a presentation choice. An invalid account ID, inventory count, or payment amount should usually stay visible as a failure. int_or does not validate input, explain what went wrong, or prove that the resulting number is sensible. It lets the programmer say, right where the conversion happens, that this particular failure may become this particular integer.

The rest of 0.5.5 is considerably less tiny. Redis-backed job workers now require Redis 7.0 or Valkey 7.2, workers sharing a queue must be upgraded together, several worker processes can share a group, built-in OAuth callback routing is fixed, monitoring probes gain start deadlines, and Linux ARMv7 joins the release builds.[2] Anyone upgrading job infrastructure should read the migration notes rather than getting distracted by my banana.

Still, small functions reveal a language's taste. A conversion can preserve failure for code that needs to know, while a companion function makes deliberate defaults cheap. Good error handling gives each mistake the volume it deserves, so a harmless bad page number can fall back while a bad number that changes the job interrupts it.

Sources

[1] NTNT v0.5.5 release

[2] NTNT v0.5.5 release notes

[3] NTNT standard library: int_or

[4] Issue #128: the case for int_or