diff --git a/main.go b/main.go index 7e79c61..bfd0351 100644 --- a/main.go +++ b/main.go @@ -24,10 +24,23 @@ var verbose io.Writer = os.Stderr func main() { if err := testableMain(os.Stdout, os.Args[1:]); err != nil { fmt.Fprintln(os.Stderr, err) - os.Exit(1) + + if isRateLimitErr(err) { + fmt.Println("Github API limit reached. Soft exiting") + } else { + os.Exit(1) + } } } +func isRateLimitErr(err error) bool { + if err == nil { + return false + } + + return strings.Contains(err.Error(), "API rate limit exceeded") +} + func testableMain(stdout io.Writer, args []string) error { opts, err := getOptions(stdout, args) if err != nil { diff --git a/main_test.go b/main_test.go index 95e757a..855f92d 100644 --- a/main_test.go +++ b/main_test.go @@ -2,6 +2,7 @@ package main import ( "bytes" + "fmt" "io/ioutil" "os" "os/exec" @@ -643,6 +644,33 @@ func TestNotifications(t *testing.T) { } } +func TestIsRateLimitErr(t *testing.T) { + cases := []struct { + err error + expected bool + }{ + { + err: fmt.Errorf("graphql: API rate limit exceeded for user ID 12345"), + expected: true, + }, { + err: nil, + expected: false, + }, { + err: fmt.Errorf("fake top error"), + expected: false, + }, { + err: fmt.Errorf("something something: API rate limit exceeded for user ID 12345"), + expected: true, + }, + } + + for _, tc := range cases { + if isRateLimitErr(tc.err) != tc.expected { + t.Errorf("expected %v got %v for %s", tc.expected, !tc.expected, tc.err) + } + } +} + // memfs is an in-memory implementation of the FS interface. type memfs map[string]string