Skip to content

Commit e6de3b2

Browse files
committed
Retry few times if curl fails
1 parent d265965 commit e6de3b2

File tree

1 file changed

+53
-47
lines changed

1 file changed

+53
-47
lines changed

app/Foliage/RemoteAsset.hs

Lines changed: 53 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -58,58 +58,64 @@ addFetchRemoteAssetRule cacheDir = addBuiltinRule noLint noIdentity run
5858

5959
newETag <-
6060
withTempFile $ \etagFile -> do
61-
liftIO $ BS.writeFile etagFile oldETag
6261
liftIO $ createDirectoryIfMissing True (takeDirectory path)
63-
(Exit exitCode, Stdout out) <-
64-
traced "curl" $
65-
cmd
66-
Shell
67-
[ "curl",
68-
-- Silent or quiet mode. Do not show progress meter or error messages. Makes Curl mute.
69-
"--silent",
70-
-- Fail fast with no output at all on server errors.
71-
"--fail",
72-
-- If the server reports that the requested page has moved to a different location this
73-
-- option will make curl redo the request on the new place.
74-
-- NOTE: This is needed because github always replies with a redirect
75-
"--location",
76-
-- This option makes a conditional HTTP request for the specific ETag read from the
77-
-- given file by sending a custom If-None-Match header using the stored ETag.
78-
-- For correct results, make sure that the specified file contains only a single line
79-
-- with the desired ETag. An empty file is parsed as an empty ETag.
80-
"--etag-compare",
81-
etagFile,
82-
-- This option saves an HTTP ETag to the specified file. If no ETag is sent by the server,
83-
-- an empty file is created.
84-
"--etag-save",
85-
etagFile,
86-
-- Write output to <file> instead of stdout.
87-
"--output",
88-
path,
89-
"--write-out",
90-
"%{json}",
91-
-- URL to fetch
92-
show uri
93-
]
94-
case exitCode of
95-
ExitSuccess -> liftIO $ BS.readFile etagFile
96-
ExitFailure c -> do
97-
-- We show the curl exit code only if we cannot parse curl's write-out.
98-
-- If we can parse it, we can craft a better error message.
99-
case Aeson.eitherDecode out :: Either String CurlWriteOut of
100-
Left err ->
101-
error $
102-
unlines
103-
[ "curl failed with return code " ++ show c ++ " while fetching " ++ show uri,
104-
"Error while reading curl diagnostic: " ++ err
105-
]
106-
-- We can consider displaying different messages based on some fields (e.g. response_code)
107-
Right CurlWriteOut {errormsg} ->
108-
error errormsg
62+
liftIO $ BS.writeFile etagFile oldETag
63+
actionRetry 5 $ runCurl uri path etagFile
10964

11065
let changed = if newETag == oldETag then ChangedRecomputeSame else ChangedRecomputeDiff
11166
return $ RunResult {runChanged = changed, runStore = newETag, runValue = path}
11267

68+
runCurl :: URI -> String -> String -> Action ETag
69+
runCurl uri path etagFile = do
70+
(Exit exitCode, Stdout out) <-
71+
traced "curl" $
72+
cmd
73+
Shell
74+
[ "curl",
75+
-- Silent or quiet mode. Do not show progress meter or error messages. Makes Curl mute.
76+
"--silent",
77+
-- Fail fast with no output at all on server errors.
78+
"--fail",
79+
-- If the server reports that the requested page has moved to a different location this
80+
-- option will make curl redo the request on the new place.
81+
-- NOTE: This is needed because github always replies with a redirect
82+
"--location",
83+
-- This option makes a conditional HTTP request for the specific ETag read from the
84+
-- given file by sending a custom If-None-Match header using the stored ETag.
85+
-- For correct results, make sure that the specified file contains only a single line
86+
-- with the desired ETag. An empty file is parsed as an empty ETag.
87+
"--etag-compare",
88+
etagFile,
89+
-- This option saves an HTTP ETag to the specified file. If no ETag is sent by the server,
90+
-- an empty file is created.
91+
"--etag-save",
92+
etagFile,
93+
-- Write output to <file> instead of stdout.
94+
"--output",
95+
path,
96+
"--write-out",
97+
"%{json}",
98+
-- URL to fetch
99+
show uri
100+
]
101+
case exitCode of
102+
ExitSuccess -> liftIO $ BS.readFile etagFile
103+
ExitFailure c -> do
104+
-- We show the curl exit code only if we cannot parse curl's write-out.
105+
-- If we can parse it, we can craft a better error message.
106+
case Aeson.eitherDecode out :: Either String CurlWriteOut of
107+
Left err ->
108+
error $
109+
unlines
110+
[ "curl failed with return code " ++ show c ++ " while fetching " ++ show uri,
111+
"Error while reading curl diagnostic: " ++ err
112+
]
113+
-- We can consider displaying different messages based on some fields (e.g. response_code)
114+
Right CurlWriteOut {errormsg} ->
115+
error errormsg
116+
117+
type ETag = BS.ByteString
118+
113119
-- Add what you need. See https://everything.curl.dev/usingcurl/verbose/writeout.
114120
newtype CurlWriteOut = CurlWriteOut
115121
{errormsg :: String}

0 commit comments

Comments
 (0)