Stream: beginners

Topic: Inferred error union


view this post on Zulip Maxime Pigeon (Aug 23 2026 at 14:35):

Hi! Say I've got an HTTP request handler calling a bunch of functions that can fail. Is there a way for the handler to return a Try with a union of all the errors, without having to specify all the error tags in the signature? In other words, can Roc infer the error set like in Zig?

view this post on Zulip Maxime Pigeon (Aug 23 2026 at 14:37):

I tried handler : Server.Request => Try(Response, _) and handler : Server.Request => Try(Response, [..]) but it doesn't seem to work.

view this post on Zulip Maxime Pigeon (Aug 23 2026 at 14:39):

I understand I can convert the different errors into, say, a ServerErr, but then I've got a bunch of can_fail() ? |err| ServerErr(Str.inspect(err).

view this post on Zulip boof (Aug 23 2026 at 16:14):

I've run into the related issue, I suppose. In the example below there is a function parse_uri which is needed to use ?

I suppose the root cause of it is ParseErr which is not open union tag

Code

view this post on Zulip Maxime Pigeon (Aug 23 2026 at 20:40):

Here's another example:

read_json! : Server.Request => Try(Str, _)
read_json! = |request|
    request.body().with_limit(16 * 1024).read_all!()?
        |> Str.from_utf8

Ideally, the inferred type would be [BadUtf8, RequestBodyErr] or something like that, but I get a type mismatch. I suppose, like @boof , it's because read_all!'s error union is closed?

view this post on Zulip Aurélien Geron (Aug 23 2026 at 21:03):

Yes, it's probably because read_all! returns a closed union. You can work around this issue by using (x.read_all!() ? |RequestBodyErr(err)|RequestBodyErr(err)). Not ideal, but hopefully this will become automatic in the future.

view this post on Zulip Luke Boswell (Aug 23 2026 at 21:30):

Aurélien Geron said:

Yes, it's probably because read_all! returns a closed union. You can work around this issue by using (x.read_all!() ? |RequestBodyErr(err)|RequestBodyErr(err)). Not ideal, but hopefully this will become automatic in the future.

I believe this is what @Jared Ramirez is working on in https://github.com/roc-lang/roc/pull/10434


Last updated: Sep 03 2026 at 15:16 UTC