Skip to content

Instantly share code, notes, and snippets.

@tomprogers
Last active January 19, 2017 22:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tomprogers/968a08c674e8be5390649dc2af08c6ab to your computer and use it in GitHub Desktop.
Save tomprogers/968a08c674e8be5390649dc2af08c6ab to your computer and use it in GitHub Desktop.
I wanted to find out which HTTP status codes cause fetch to resolve, and which to reject
/**
* Map HTTP error codes to fetch's .then/.catch behavior
* List based on https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
*/
let codes = [
{"code": "100", "text": "Continue"},
{"code": "101", "text": "Switching Protocol"},
{"code": "200", "text": "OK"},
{"code": "201", "text": "Created"},
{"code": "202", "text": "Accepted"},
{"code": "203", "text": "Non-Authoritative Information"},
{"code": "204", "text": "No Content"},
{"code": "205", "text": "Reset Content"},
{"code": "206", "text": "Partial Content"},
{"code": "300", "text": "Multiple Choice"},
{"code": "301", "text": "Moved Permanently"},
{"code": "302", "text": "Found"},
{"code": "303", "text": "See Other"},
{"code": "304", "text": "Not Modified"},
{"code": "305", "text": "Use Proxy"},
{"code": "306", "text": "unused"},
{"code": "307", "text": "Temporary Redirect"},
{"code": "308", "text": "Permanent Redirect"},
{"code": "400", "text": "Bad Request"},
{"code": "401", "text": "Unauthorized"},
{"code": "402", "text": "Payment Required"},
{"code": "403", "text": "Forbidden"},
{"code": "404", "text": "Not Found"},
{"code": "405", "text": "Method Not Allowed"},
{"code": "406", "text": "Not Acceptable"},
{"code": "407", "text": "Proxy Authentication Required"},
{"code": "408", "text": "Request Timeout"},
{"code": "409", "text": "Conflict"},
{"code": "410", "text": "Gone"},
{"code": "411", "text": "Length Required"},
{"code": "412", "text": "Precondition Failed"},
{"code": "413", "text": "Payload Too Large"},
{"code": "414", "text": "URI Too Long"},
{"code": "415", "text": "Unsupported Media Type"},
{"code": "416", "text": "Requested Range Not Satisfiable"},
{"code": "417", "text": "Expectation Failed"},
{"code": "421", "text": "Misdirected Request"},
{"code": "426", "text": "Upgrade Required"},
{"code": "428", "text": "Precondition Required"},
{"code": "429", "text": "Too Many Requests"},
{"code": "431", "text": "Request Header Fields Too Large"},
{"code": "451", "text": "Unavailable For Legal Reasons"},
{"code": "500", "text": "Internal Server Error"},
{"code": "501", "text": "Not Implemented"},
{"code": "502", "text": "Bad Gateway"},
{"code": "503", "text": "Service Unavailable"},
{"code": "504", "text": "Gateway Timeout"},
{"code": "505", "text": "HTTP Version Not Supported"},
{"code": "506", "text": "Variant Also Negotiates"},
{"code": "507", "text": "Variant Also Negotiates"},
{"code": "511", "text": "Network Authentication Required"}
];
codes.map(({ code , text }) => {
let start = new Date();
fetch(`http://localhost:8080/?code=${code}`)
.then((response) => {
console.log(`${code} -> resolve`);
})
.catch((reason) => {
let end = new Date();
let elapsed = end.getTime() - start.getTime();
console.log(`${code} -> reject reason=${reason} (${elapsed}ms)`);
});
});

With three exceptions, fetch resolves for every status code (including 5xx) as long as a response is received.

The three exceptions are:

  • HTTP 100 Continue
  • HTTP 101 Switching Protocol
  • HTTP 407 Proxy Authentication Required

Both 1xx codes rejected after a 120-second delay. I assume this is because both 1xx codes are intended for multi-request scenarios, and my simple test doesn't follow through on that. The 120-second delay is, presumably, Chrome's default timeout.

The 407 rejects immediately.

All three reject with a TypeError. Which is the same thing you get when e.g. there's no network connection (e.g. no wifi).

/**
* Dead-simple HTTP server that returns any status code you ask for, e.g.:
*
* GET / | returns an HTTP 200
* GET /?code=302 | returns an HTTP 302
* etc., for any 3-digit numeric value
*/
var http = require('http');
var server = http.createServer(function(req, res) {
var desiredStatusCode = 200;
try {
desiredStatusCode = parseInt(req.url.match(/[?&]code=(\d{3})\D?/i)[1]);
} catch(e) {}
res.writeHead(desiredStatusCode, {
'Content-Type': 'text/plain',
'Location': 'http://localhost:8080/' // to ensure redirects end quickly; is ignored when paired with non-3xx statuses
});
res.end('done');
});
server.listen(8080, function() {
console.log("Server listening on: http://localhost:%s", 8080);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment