Skip to content

Rest client support for endpoint not returning a JSON #161

Open
@nobe4

Description

@nobe4

Problem statement

While working on gh-not I started experimenting with Actors interacting with the GitHub API.

A very simple one would be to mark a notification as read, as per https://docs.github.com/en/rest/activity/notifications?apiVersion=2022-11-28#mark-a-thread-as-read.

Here's a simplified version of the code I wanted to use:

func main() {
	client, err := api.DefaultRESTClient()
	if err != nil {
		panic(err)
	}

	url := "https://api.github.com/notifications/threads/[REDACTED]"

	resp := []interface{}{}
	err = client.Patch(url, nil, &resp)
	if err != nil {
		panic(err)
	}

}

And I always get: panic: unexpected end of JSON input

Possible fix 1

The documentation specifies status codes, but no response content; expecting one is thus useless in this context.

I wonder if

b, err := io.ReadAll(resp.Body)
if err != nil {
return err
}
err = json.Unmarshal(b, &response)
if err != nil {
return err
}
could be modified in the following way:

	b, err := io.ReadAll(resp.Body)
	if err != nil {
		return err
	}

+        if len(b) > 0{
        	err = json.Unmarshal(b, &response)
        	if err != nil {
        		return err
        	}
+        }

This would prevent breaking on invalid JSON when none is expected.

POC implemented in #162

Possible fix 2

The 205 status code spec specifies:

a server MUST NOT generate content in a 205 response

So maybe a better fix would be:

	if resp.StatusCode == http.StatusNoContent {
		return nil
	}

+	if resp.StatusCode == http.StatusResetContent {
+		return nil
+	}

Implementation PR: #163

Current workaround

func main() {
	client, err := api.DefaultRESTClient()
	if err != nil {
		panic(err)
	}

	url := "https://api.github.com/notifications/threads/[REDACTED]"

	resp := []interface{}{}
	err = client.Patch(url, nil, &resp)
	if err != nil && err.Error() != "unexpected end of JSON input" {
		panic(err)
	}
        // continue as planned
}

Additional questions

  • Is there another way to use go-gh's REST client for Patch requests if the endpoint doesn't return a valid JSON?
  • Would there be any benefits in returning the response code from those requests? It seems that implementing custom logic solely based on JSON breaks as soon as no JSON is returned

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions