Can I Make cURL Fail with an exitCode Different Than 0 If the Http Status Code Is Not 200?
I Was Always Assuming That When Curl Got an Http 500 Response It Was Returning an Exit Code That Meant Failure (! = 0), but That Seems to Be Not the Case. Is...
I was always assuming that when curl got an HTTP 500 response it was returning an exit code that meant failure (!= 0), but that seems to be not the case.
Is there a way I can I make cURL fail with an exitCode different than 0 if the HTTP status code is not 200? I know I can use -w "%{http_code}" but that puts it in STDOUT, not as the exit code (besides, I'm also interested in capturing the output, which I don't want to redirect to a file, but to the screen).
11 Answers
Most of the answers provided so far will not print the HTTP response body in case an HTTP request fails.
If you would like to print the response body as well, even if the exit code is non-zero due to the HTTP request failing: provided you have curl v7.76 or newer, simply use curl --fail-with-body.
For older versions of curl, try this:
curlf() {
OUTPUT_FILE=$(mktemp)
HTTP_CODE=$(curl --silent --output $OUTPUT_FILE --write-out "%{http_code}" "$@")
if [[ ${HTTP_CODE} -lt 200 || ${HTTP_CODE} -gt 299 ]] ; then
>&2 cat $OUTPUT_FILE
return 22
fi
cat $OUTPUT_FILE
rm $OUTPUT_FILE
}
curl --fail does part of what you want:
from man curl:
-f, --fail(HTTP) Fail silently (no output at all) on server errors. This is mostly done to better enable scripts etc to better deal with failed attempts. In normal cases when an HTTP server fails to deliver a document, it returns an HTML document stating so (which often also describes why and more). This flag will prevent curl from outputting that and return error 22.
This method is not fail-safe and there are occasions where non-successful response codes will slip through, especially when authentication is involved (response codes 401 and 407).
But it blocks output to the screen.
If you just want to display the contents of the curled page, you can do this:
STATUSCODE=$(curl --silent --output /dev/stderr --write-out "%{http_code}" URL)
if test $STATUSCODE -ne 200; then
# error handling
fi
This writes the page's content to STDERR while writing the HTTP status code to STDOUT, so it can be assigned to the variable STATUSCODE.
I was able to do it using a combination of flags:
curl --silent --show-error --fail URL
--silent hides the progress and error
--show-error shows the error message hidden by --silent
--fail returns an exit code > 0 when the request fails
Use --fail-with-body. This will cause curl to exit with status code 22 when response code is >=400.
Note though that this flag is brand new (as of 2021/02/15), and was added in version 7.76.0, which postdates @rampion's answer. Thus it might not be available on your system.
--fail-with-body
(HTTP) Return an error on server errors where the HTTP response code is 400 or greater). In normal cases when an HTTP server fails to deliver a document, it returns an HTML document stating so (which often also describes why and more). This flag will still allow curl to outputting and save that content but also to return error 22.
This is an alternative option to -f, --fail which makes curl fail for the same circumstances but without saving the content.
See also -f, --fail. Added in 7.76.0.