bitfield / script

Making it easy to write shell-like scripts in Go
MIT License
5.57k stars 315 forks source link

Handling Response Status Codes of HTTP #214

Open sortira opened 2 months ago

sortira commented 2 months ago

In the Do function of the Pipe object, all HTTP response codes of 2xx are treated as okay. While this is a good generalisation, a possible enhancement could be to create a dictionary containing helpful messages for the various HTTP codes and display the appropriate ones for completeness sake and provide finer control to the user who might want to perform different tasks based on different response codes.

https://github.com/bitfield/script/blob/0296fd262daeaf6178a11303b86d3f65c00fccf7/script.go#L320

bitfield commented 2 months ago

What did you have in mind exactly? Could you provide an example program and show what it would produce?

sortira commented 2 months ago

What did you have in mind exactly? Could you provide an example program and show what it would produce?

Not sure if the repo would accept a PR, I could create one and the code could be reviewed.

bitfield commented 2 months ago

Just post it here as a comment if you like.

sortira commented 2 months ago

@bitfield here you go.

var httpStatusMessages = map[int]string{
    200: "OK",
    201: "Created",
    202: "Accepted",
    204: "No Content",
    400: "Bad Request",
    401: "Unauthorized",
    403: "Forbidden",
    404: "Not Found",
    500: "Internal Server Error",
    502: "Bad Gateway",
    503: "Service Unavailable",
    504: "Gateway Timeout",
}
func (p *Pipe) Do(req *http.Request) *Pipe {
    return p.Filter(func(r io.Reader, w io.Writer) error {
        resp, err := p.httpClient.Do(req)
        if err != nil {
            return err
        }
        defer resp.Body.Close()

        _, err = io.Copy(w, resp.Body)
        if err != nil {
            return err
        }

        // Get the status message from the dictionary, or a default message if not found
        statusMessage, found := httpStatusMessages[resp.StatusCode]
        if !found {
            statusMessage = "Unknown Status Code"
        }

        // Any HTTP 2xx status code is considered okay
        if resp.StatusCode/100 != 2 {
            return fmt.Errorf("unexpected HTTP response status: %s (%s)", resp.Status, statusMessage)
        }

        fmt.Printf("HTTP response status: %s (%s)\n", resp.Status, statusMessage)
        return nil
    })
}

PS: This repo was suggested by the good-first-issues label for my Hacktoberfest preparation, so feedbacks will be welcome!

bitfield commented 2 months ago

Right, but the question is how would such a feature be used? You mentioned:

provide finer control to the user who might want to perform different tasks based on different response codes.

So can you write an example program that does this? Then we'll see if the API is a good fit for the problem or not.