Pragmatism in the real world

Only display body on error with curl

Sometimes, I only want to display the response from a curl request if it errors – i.e. the status code is 400 or higher.

With curl 7.76 or greater this is done using the --fail-with-body parameter:

curl -s --fail-with-body \
    https://api.example.com/foo/${id} \
    -H "Content-Type: application/json" \
    --data "@data.json"

On success, the return code ($?) is 0 and on failure the body is output with the return code set to 22.

Prior to 7.76, you can write a script that looks something like this:

#!/usr/bin/env bash

output=$(mktemp)
trap '{ rm -f -- "$output"; }' EXIT

code=$(curl -s --output "$output" --write-out '%{http_code}' \
    https://api.example.com/foo/${id} \
    -H "Content-Type: application/json" \
    --data "@data.json"

if [ $code -ge 400 ]; then
    cat $output
    exit 22
fi

In this case, we use --output to write the body to a temporary file (which we remove on exit of script via trap) and --write-out to write the status code to the local variable code and then test it. The end result is that we only display the output if the HTTP status code is 400 or greater.

Much easier to upgrade to the latest curl though!