Improve HTTP errors (#1253)

* Improve HTTP errors

Fixes https://github.com/dhall-lang/dhall-haskell/issues/1251

This improves HTTP error messages by:

* Expanding the set of recognized status codes
* Adding up to 7 lines of the response body

For example:

```
Error: Remote file missing

URL:

↳ https://httpbin.org/statu

Message:

1│ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
2│ <title>404 Not Found</title>
3│ <h1>Not Found</h1>
4│ <p>The requested URL was not found on the server.  If you entered the URL manually please check your spelling and try again.</p>
```

* Always include HTTP status code in output

... as suggested by @sjakobi

* Use "not found" wording for 404 message

This is closer to the official wording for the error message

* Compress error message formatting

There's no need to put the URL and status code on separate lines since
they are compact
This commit is contained in:
Gabriel Gonzalez 2019-08-29 13:01:43 -05:00 committed by mergify[bot]
parent eb8b6101a9
commit 9ff63b2234

View File

@ -61,49 +61,100 @@ renderPrettyHttpException _ (InvalidUrlException _ r) =
"\n"
<> "\ESC[1;31mError\ESC[0m: Invalid URL\n"
<> "\n"
<> " " <> show r <> "\n"
<> "URL: " <> show r <> "\n"
renderPrettyHttpException url (HttpExceptionRequest _ e) =
case e of
ConnectionFailure _ ->
"\n"
<> "\ESC[1;31mError\ESC[0m: Remote host not found\n"
<> "\n"
<> "URL:\n"
<> "\n"
<> "" <> url <> "\n"
<> "URL: " <> url <> "\n"
InvalidDestinationHost host ->
"\n"
<> "\ESC[1;31mError\ESC[0m: Invalid remote host name:\n"
<> "\n"
<> " " <> show host <> "\n"
<> "Host: " <> show host <> "\n"
ResponseTimeout ->
"\n"
<> "\ESC[1;31mError\ESC[0m: The remote host took too long to respond\n"
<> "\n"
<> "URL:\n"
<> "\n"
<> "" <> url <> "\n"
StatusCodeException response _
| statusCode == 404 ->
"\n"
<> "\ESC[1;31mError\ESC[0m: Remote file not found\n"
<> "\n"
<> "URL:\n"
<> "\n"
<> "" <> url <> "\n"
| otherwise ->
"\n"
<> "\ESC[1;31mError\ESC[0m: Unexpected HTTP status code:\n"
<> "\n"
<> "" <> show statusCode <> "\n"
<> "\n"
<> "URL:\n"
<> "\n"
<> "" <> url <> "\n"
<> "URL: " <> url <> "\n"
StatusCodeException response body -> prefix <> suffix
where
prefix
| statusCode == 401 =
"\n"
<> "\ESC[1;31mError\ESC[0m: Access unauthorized\n"
| statusCode == 403 =
"\n"
<> "\ESC[1;31mError\ESC[0m: Access forbidden\n"
| statusCode == 404 =
"\n"
<> "\ESC[1;31mError\ESC[0m: Remote file not found\n"
| statusCode == 500 =
"\n"
<> "\ESC[1;31mError\ESC[0m: Server-side failure\n"
| statusCode == 502 =
"\n"
<> "\ESC[1;31mError\ESC[0m: Upstream failure\n"
| statusCode == 503 =
"\n"
<> "\ESC[1;31mError\ESC[0m: Server temporarily unavailable\n"
| statusCode == 504 =
"\n"
<> "\ESC[1;31mError\ESC[0m: Upstream timeout\n"
| otherwise =
"\n"
<> "\ESC[1;31mError\ESC[0m: HTTP request failure\n"
suffix =
"\n"
<> "HTTP status code: " <> show statusCode <> "\n"
<> "\n"
<> "URL: " <> url <> "\n"
<> message
statusCode =
Network.HTTP.Types.statusCode
(HTTP.responseStatus response)
message =
case Data.Text.Encoding.decodeUtf8' body of
Left _ ->
"\n"
<> "Message (non-UTF8 bytes):\n"
<> "\n"
<> truncatedBodyString <> "\n"
where
bodyString = show body
dots = ""
truncatedLength = 80 - length dots
truncatedBodyString
| truncatedLength < length bodyString =
take truncatedLength bodyString <> dots
| otherwise =
bodyString
Right "" ->
""
Right bodyText ->
"\n"
<> "Message:\n"
<> "\n"
<> Text.unpack prefixedText
where
prefixedLines =
zipWith combine prefixes (Text.lines bodyText)
where
prefixes =
map (Text.pack . show) [(1 ::Int)..7] ++ [ "" ]
combine n line = n <> "" <> line
prefixedText = Text.unlines prefixedLines
e' -> "\n" <> show e' <> "\n"
#else
renderPrettyHttpException url e = case e of
@ -111,18 +162,16 @@ renderPrettyHttpException url e = case e of
"\n"
<> "\ESC[1;31mError\ESC[0m: Wrong host:\n"
<> "\n"
<> " " <> show e' <> "\n"
<> "Host: " <> show e' <> "\n"
InvalidDestinationHost host ->
"\n"
<> "\ESC[1;31mError\ESC[0m: Invalid host name:\n"
<> "\n"
<> " " <> show host <> "\n"
<> "Host: " <> show host <> "\n"
ResponseTimeout ->
"\ESC[1;31mError\ESC[0m: The host took too long to respond\n"
<> "\n"
<> "URL:\n"
<> "\n"
<> "" <> url <> "\n"
<> "URL: " <> url <> "\n"
e' -> "\n"
<> show e' <> "\n"
#endif