GNU bug report logs - #52577
‘guix lint’ throws an ugly backtrace if the GitHub updater receives “rate limit exceeded” error

Previous Next

Package: guix;

Reported by: Xinglu Chen <public <at> yoctocell.xyz>

Date: Fri, 17 Dec 2021 14:04:01 UTC

Severity: important

Done: Ludovic Courtès <ludo <at> gnu.org>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 52577 in the body.
You can then email your comments to 52577 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-guix <at> gnu.org:
bug#52577; Package guix. (Fri, 17 Dec 2021 14:04:01 GMT) Full text and rfc822 format available.

Acknowledgement sent to Xinglu Chen <public <at> yoctocell.xyz>:
New bug report received and forwarded. Copy sent to bug-guix <at> gnu.org. (Fri, 17 Dec 2021 14:04:01 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Xinglu Chen <public <at> yoctocell.xyz>
To: bug-guix <at> gnu.org
Subject: ‘guix lint’ throws an ugly backtrace if the
 GitHub updater receives
 “rate limit exceeded” error
Date: Fri, 17 Dec 2021 15:03:36 +0100
[Message part 1 (text/plain, inline)]
When running ‘guix lint -c refresh’ on a package hosted on GitHub, I get
an ugly backtrace when the GitHub rate limit has been reached.

--8<---------------cut here---------------start------------->8---
$ guix lint pipewire
fetching CVE database for 2021...
fetching CVE database for 2018...
Backtrace:ipewire <at> 0.3.29 [refresh]...
          15 (primitive-load "/home/yoctocell/.config/guix/current/b…")
In guix/ui.scm:
   2206:7 14 (run-guix . _)
  2169:10 13 (run-guix-command _ . _)
In ice-9/boot-9.scm:
  1752:10 12 (with-exception-handler _ _ #:unwind? _ # _)
  1752:10 11 (with-exception-handler _ _ #:unwind? _ # _)
In guix/store.scm:
   658:37 10 (thunk)
In srfi/srfi-1.scm:
    634:9  9 (for-each #<procedure 7fb8f038ff40 at guix/scripts/lin…> …)
In guix/scripts/lint.scm:
     65:4  8 (run-checkers _ _ #:store _)
In srfi/srfi-1.scm:
    634:9  7 (for-each #<procedure 7fb8e15a8d20 at guix/scripts/lin…> …)
In guix/scripts/lint.scm:
    74:21  6 (_ _)
In guix/lint.scm:
   1428:5  5 (check-for-updates #<package pipewire <at> 0.3.29 gnu/packag…>)
    771:2  4 (call-with-networking-fail-safe _ _ _)
In ice-9/boot-9.scm:
  1752:10  3 (with-exception-handler _ _ #:unwind? _ # _)
  1685:16  2 (raise-exception _ #:continuable? _)
  1683:16  1 (raise-exception _ #:continuable? _)
  1685:16  0 (raise-exception _ #:continuable? _)

ice-9/boot-9.scm:1685:16: In procedure raise-exception:
ERROR:
  1. &http-get-error:
      uri: #<<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"
  2. &message: "https://api.github.com/repos/PipeWire/pipewire/releases: HTTP download failed: 403 (\"rate limit exceeded\")"
--8<---------------cut here---------------end--------------->8---

When running ‘guix refresh’, a much friendlier error message is produced.

--8<---------------cut here---------------start------------->8---
$ guix refresh -t github
guix refresh: error: https://api.github.com/repos/OpenZWave/open-zwave/releases: HTTP download failed: 403 ("rate limit exceeded")
--8<---------------cut here---------------end--------------->8---

The problem seems to be that the ‘check-for-updates’ procedure in (guix
lint) doesn’t catch the ‘&http-get-error’.  I tried adding the following
form:

--8<---------------cut here---------------start------------->8---
(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 ...))
--8<---------------cut here---------------end--------------->8---

but it doesn’t work.  C seems to be something a lot more complicated
than just a ‘&http-get-error’:

--8<---------------cut here---------------start------------->8---
#<&compound-exception components: (#<&error> #<&irritants irritants: (#<&compound-exception components: (#<&http-get-error uri: #<<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: #<<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---

Any ideas on how to extract to the ‘&http-get-error’?
[signature.asc (application/pgp-signature, inline)]

Information forwarded to bug-guix <at> gnu.org:
bug#52577; Package guix. (Fri, 17 Dec 2021 16:30:03 GMT) Full text and rfc822 format available.

Message #8 received at 52577 <at> debbugs.gnu.org (full text, mbox):

From: Maxime Devos <maximedevos <at> telenet.be>
To: Xinglu Chen <public <at> yoctocell.xyz>, 52577 <at> debbugs.gnu.org
Subject: Re: bug#52577: ‘guix lint’
 throws an ugly backtrace if the GitHub updater receives
 “rate limit exceeded” error
Date: Fri, 17 Dec 2021 16:29:35 +0000
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?

If you do the latter, you'll have to check the 'uri' field of the
&http-get-error to determine if it's GitHub, and not, say,
SWH or the CVE database or something.

Greetings,
Maxime.





Information forwarded to bug-guix <at> gnu.org:
bug#52577; Package guix. (Sun, 19 Dec 2021 11:59:02 GMT) Full text and rfc822 format available.

Message #11 received at 52577 <at> debbugs.gnu.org (full text, mbox):

From: Maxime Devos <maximedevos <at> telenet.be>
To: Xinglu Chen <public <at> yoctocell.xyz>, 52577 <at> debbugs.gnu.org
Subject: Re: bug#52577: ‘guix lint’
 throws an ugly backtrace if the GitHub updater receives
 “rate limit exceeded” error
Date: Sun, 19 Dec 2021 11:58:25 +0000
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:
> #<<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: #<<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: #<<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.

Greetings,
Maxime





Information forwarded to bug-guix <at> gnu.org:
bug#52577; Package guix. (Tue, 21 Dec 2021 17:18:02 GMT) Full text and rfc822 format available.

Message #14 received at 52577 <at> debbugs.gnu.org (full text, mbox):

From: Xinglu Chen <public <at> yoctocell.xyz>
To: Maxime Devos <maximedevos <at> telenet.be>, 52577 <at> debbugs.gnu.org
Subject: Re: bug#52577: ‘guix lint’ throws an ugly
 backtrace if the GitHub
 updater receives “rate limit exceeded” error
Date: Tue, 21 Dec 2021 18:17:08 +0100
[Message part 1 (text/plain, inline)]
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:
>> #<<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: #<<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: #<<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))
        ...)
        ...))

[0001-lint-Fix-handling-of-HTTP-errors.patch (text/x-patch, attachment)]
[signature.asc (application/pgp-signature, inline)]

Information forwarded to bug-guix <at> gnu.org:
bug#52577; Package guix. (Tue, 21 Dec 2021 17:34:02 GMT) Full text and rfc822 format available.

Message #17 received at 52577 <at> debbugs.gnu.org (full text, mbox):

From: Maxime Devos <maximedevos <at> telenet.be>
To: Xinglu Chen <public <at> yoctocell.xyz>, 52577 <at> debbugs.gnu.org
Subject: Re: bug#52577: ‘guix lint’
 throws an ugly backtrace if the GitHub updater receives
 “rate limit exceeded” error
Date: Tue, 21 Dec 2021 17:32:58 +0000
Xinglu Chen schreef op di 21-12-2021 om 18:17 [+0100]:
> O[...]
> Yeah, the catch/throw system doesn’t really work well with ‘raise’.
> Here is what I found after some digging: [...]

My point was that a raise-style exception shouldn't be wrapped in a
(%exception ...) and then again in an &exception-with-kind-and-args,
this wrapping should ‘collapse’. Seems like a bug in Guile.

Anyway, your patch to Guix looks reasonable to me, though it would be a
good idea to look into fixing the double-wrapping in Guile.


Greetings,
Maxime.





Information forwarded to bug-guix <at> gnu.org:
bug#52577; Package guix. (Tue, 21 Dec 2021 21:50:01 GMT) Full text and rfc822 format available.

Message #20 received at 52577 <at> debbugs.gnu.org (full text, mbox):

From: Xinglu Chen <public <at> yoctocell.xyz>
To: Maxime Devos <maximedevos <at> telenet.be>, 52577 <at> debbugs.gnu.org
Subject: Re: bug#52577: ‘guix lint’ throws an ugly
 backtrace if the GitHub
 updater receives “rate limit exceeded” error
Date: Tue, 21 Dec 2021 22:49:20 +0100
[Message part 1 (text/plain, inline)]
On Tue, Dec 21 2021, Maxime Devos wrote:

> Xinglu Chen schreef op di 21-12-2021 om 18:17 [+0100]:
>> O[...]
>> Yeah, the catch/throw system doesn’t really work well with ‘raise’.
>> Here is what I found after some digging: [...]
>
> My point was that a raise-style exception shouldn't be wrapped in a
> (%exception ...) and then again in an &exception-with-kind-and-args,
> this wrapping should ‘collapse’. Seems like a bug in Guile.

OK, thanks for the clarification.

> Anyway, your patch to Guix looks reasonable to me, though it would be a
> good idea to look into fixing the double-wrapping in Guile.

Cool, fixing the issue in Guile itself would be great, I might look into
it in the future.  :-)
[signature.asc (application/pgp-signature, inline)]

Severity set to 'important' from 'normal' Request was from Ludovic Courtès <ludo <at> gnu.org> to control <at> debbugs.gnu.org. (Fri, 11 Mar 2022 22:22:01 GMT) Full text and rfc822 format available.

Reply sent to Ludovic Courtès <ludo <at> gnu.org>:
You have taken responsibility. (Sat, 14 May 2022 14:19:02 GMT) Full text and rfc822 format available.

Notification sent to Xinglu Chen <public <at> yoctocell.xyz>:
bug acknowledged by developer. (Sat, 14 May 2022 14:19:02 GMT) Full text and rfc822 format available.

Message #27 received at 52577-done <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: Xinglu Chen <public <at> yoctocell.xyz>
Cc: 52577-done <at> debbugs.gnu.org
Subject: Re: bug#52577: ‘guix lint’ throws an ugly
 backtrace if the GitHub
 updater receives “rate limit exceeded” error
Date: Sat, 14 May 2022 16:18:26 +0200
Hi,

Xinglu Chen <public <at> yoctocell.xyz> skribis:

> When running ‘guix lint -c refresh’ on a package hosted on GitHub, I get
> an ugly backtrace when the GitHub rate limit has been reached.
>
> $ guix lint pipewire

[...]

>    1428:5  5 (check-for-updates #<package pipewire <at> 0.3.29 gnu/packag…>)
>     771:2  4 (call-with-networking-fail-safe _ _ _)
> In ice-9/boot-9.scm:
>   1752:10  3 (with-exception-handler _ _ #:unwind? _ # _)
>   1685:16  2 (raise-exception _ #:continuable? _)
>   1683:16  1 (raise-exception _ #:continuable? _)
>   1685:16  0 (raise-exception _ #:continuable? _)
>
> ice-9/boot-9.scm:1685:16: In procedure raise-exception:
> ERROR:
>   1. &http-get-error:
>       uri: #<<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"
>   2. &message: "https://api.github.com/repos/PipeWire/pipewire/releases: HTTP download failed: 403 (\"rate limit exceeded\")"

This was fixed in March with commit
55e8e283ae398cc476e50e822383797c5f43db4c.

Closing!

Ludo’.




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Sun, 12 Jun 2022 11:24:05 GMT) Full text and rfc822 format available.

This bug report was last modified 1 year and 290 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.