On So, Dez 19 2021, Maxime Devos wrote: > Xinglu Chen schreef op vr 17-12-2021 om 21:57 [+0100]: >> On Fri, Dec 17 2021, Maxime Devos wrote: >> >> > Xinglu Chen schreef op vr 17-12-2021 om 15:03 [+0100]: >> > > (guard (c ((and (http-get-error? c) >> > >                 (string=? "rate limit exceeded" >> > >                           (http-get-error-reason c))) >> > >            (warning (G_ "GitHub rate limit exceeded")) >> > >            #f)) >> > >   (with-networking-fail-safe ...)) >> > >> > Shouldn't this be wrapped the other way around? >> > Or maybe even move the http-get-error?+string=?+warning inside >> > call-with-networking-fail-safe? >> >> Thanks for the pointer, it seems that ‘throw’ in >> ‘call-with-networking-fail-safe’ wraps the original exception an >> additional ‘&compound-exception’.  Before the ‘throw’, the exception >> looks like this: >> >> --8<---------------cut here---------------start------------->8--- >> (%exception #<&compound-exception components: (#<&http-get-error uri: >> #< scheme: https userinfo: #f host: "api.github.com" port: #f >> path: "/repos/PipeWire/pipewire/releases" query: #f fragment: #f> >> code: 403 reason: "rate limit exceeded"> #<&message message: " >> https://api.github.com/repos/PipeWire/pipewire/releases: HTTP >> download failed: 403 (\"rate limit exceeded\")">)>) >> --8<---------------cut here---------------end--------------->8--- >> >> After the ‘throw’, it becomes this: >> >> --8<---------------cut here---------------start------------->8--- >> #<&compound-exception components: (#<&error> #<&irritants irritants: >> (#<&compound-exception >> components: (#<&http-get-error uri: #< scheme: https userinfo: >> #f host: >> "api.github.com" port: #f path: "/repos/PipeWire/pipewire/releases" >> query: #f fragment: #f> >> code: 403 reason: "rate limit exceeded"> #<&message message: >> "https://api.github.com/repos/PipeWire/pipewire/releases: HTTP >> download failed: 403 (\"rate >> limit exceeded\")">)>)> #<&exception-with-kind-and-args kind: >> %exception args: >> (#<&compound-exception components: (#<&http-get-error uri: #< >> scheme: https userinfo: >> #f host: "api.github.com" port: #f path: >> "/repos/PipeWire/pipewire/releases" query: #f >> fragment: #f> code: 403 reason: "rate limit exceeded"> #<&message >> message: >> "https://api.github.com/repos/PipeWire/pipewire/releases: HTTP >> download failed: 403 (\"rate >> limit exceeded\")">)>)>)> >> --8<---------------cut here---------------end--------------->8--- >> >> This means that the ‘guard’ form in ‘call-with-networking-fail-safe’ >> is >> never going to match anything since the real exception will always be >> nested >> in another ‘&compound-exception’. > > Actually, being wrapped in &compound-exception shouldn't be a problem: > &compound-exception just means that the exception is of multiple types, > e.g. both &message and &http-get-error or something like that. In that > case, the exception could be both message? and http-get-error?. > > I think the problem is, that for some unknown reason, the > &http-get-error/&message exception gets wrapped in a > &exception-with-and-args --- I guess there's a bad interaction with > the throw/catch exception handling system and the raise/guard system, > because only 'system-error'/'tls-certificate-error'/...-style > exceptions should get wrapped in a &exception-with-kind-and-arguments. Yeah, the catch/throw system doesn’t really work well with ‘raise’. Here is what I found after some digging: (catch KIND THUNK HANDLER) uses ‘exception-kind’ to determine the kind of the exception. Since ‘&http-get-error’ was created using ‘raise’, it doesn’t really have a notion of a “kind”, therefore, ‘exception-kind’ returns the ‘%exception’ symbol. I guess that’s why I had to match on ('%exception exception) to match the ‘&http-get-error’ Excerpt from the patch I attached: (catch #t proc (match-lambda* ... ((and ('%exception exception) (http-get-error? exception)) ...) ...))