Added PandocHttpException, trap exceptions in fetching from URLs.
Closes #3646.
This commit is contained in:
parent
d414b2543a
commit
99be906101
4 changed files with 26 additions and 9 deletions
|
@ -376,7 +376,7 @@ convertWithOpts opts = do
|
||||||
then 0
|
then 0
|
||||||
else optTabStop opts)
|
else optTabStop opts)
|
||||||
|
|
||||||
readSources :: (Functor m, MonadIO m) => [FilePath] -> m String
|
readSources :: [FilePath] -> PandocIO String
|
||||||
readSources srcs = convertTabs . intercalate "\n" <$>
|
readSources srcs = convertTabs . intercalate "\n" <$>
|
||||||
mapM readSource srcs
|
mapM readSource srcs
|
||||||
|
|
||||||
|
@ -751,6 +751,11 @@ fillMedia sourceURL d = walkM handleImage d
|
||||||
"replacing image with description"
|
"replacing image with description"
|
||||||
-- emit alt text
|
-- emit alt text
|
||||||
return $ Span ("",["image"],[]) lab
|
return $ Span ("",["image"],[]) lab
|
||||||
|
PandocHttpError u er -> do
|
||||||
|
report $ CouldNotFetchResource u
|
||||||
|
(show er ++ "\rReplacing image with description.")
|
||||||
|
-- emit alt text
|
||||||
|
return $ Span ("",["image"],[]) lab
|
||||||
_ -> throwError e)
|
_ -> throwError e)
|
||||||
handleImage x = return x
|
handleImage x = return x
|
||||||
|
|
||||||
|
@ -800,7 +805,7 @@ applyFilters mbDatadir filters args d = do
|
||||||
expandedFilters <- mapM (expandFilterPath mbDatadir) filters
|
expandedFilters <- mapM (expandFilterPath mbDatadir) filters
|
||||||
foldrM ($) d $ map (flip externalFilter args) expandedFilters
|
foldrM ($) d $ map (flip externalFilter args) expandedFilters
|
||||||
|
|
||||||
readSource :: MonadIO m => FilePath -> m String
|
readSource :: FilePath -> PandocIO String
|
||||||
readSource "-" = liftIO UTF8.getContents
|
readSource "-" = liftIO UTF8.getContents
|
||||||
readSource src = case parseURI src of
|
readSource src = case parseURI src of
|
||||||
Just u | uriScheme u `elem` ["http:","https:"] ->
|
Just u | uriScheme u `elem` ["http:","https:"] ->
|
||||||
|
@ -809,8 +814,12 @@ readSource src = case parseURI src of
|
||||||
liftIO $ UTF8.readFile (uriPath u)
|
liftIO $ UTF8.readFile (uriPath u)
|
||||||
_ -> liftIO $ UTF8.readFile src
|
_ -> liftIO $ UTF8.readFile src
|
||||||
|
|
||||||
readURI :: MonadIO m => FilePath -> m String
|
readURI :: FilePath -> PandocIO String
|
||||||
readURI src = liftIO $ (UTF8.toString . fst) <$> openURL src
|
readURI src = do
|
||||||
|
res <- liftIO $ openURL src
|
||||||
|
case res of
|
||||||
|
Left e -> throwError $ PandocHttpError src e
|
||||||
|
Right (contents, _) -> return $ UTF8.toString contents
|
||||||
|
|
||||||
readFile' :: MonadIO m => FilePath -> m B.ByteString
|
readFile' :: MonadIO m => FilePath -> m B.ByteString
|
||||||
readFile' "-" = liftIO B.getContents
|
readFile' "-" = liftIO B.getContents
|
||||||
|
|
|
@ -242,7 +242,10 @@ instance PandocMonad PandocIO where
|
||||||
newUniqueHash = hashUnique <$> (liftIO IO.newUnique)
|
newUniqueHash = hashUnique <$> (liftIO IO.newUnique)
|
||||||
openURL u = do
|
openURL u = do
|
||||||
report $ Fetching u
|
report $ Fetching u
|
||||||
liftIOError IO.openURL u
|
res <- liftIO (IO.openURL u)
|
||||||
|
case res of
|
||||||
|
Right r -> return r
|
||||||
|
Left e -> throwError $ PandocHttpError u e
|
||||||
readFileLazy s = liftIOError BL.readFile s
|
readFileLazy s = liftIOError BL.readFile s
|
||||||
readFileStrict s = liftIOError B.readFile s
|
readFileStrict s = liftIOError B.readFile s
|
||||||
readDataFile mfp fname = liftIOError (IO.readDataFile mfp) fname
|
readDataFile mfp fname = liftIOError (IO.readDataFile mfp) fname
|
||||||
|
|
|
@ -42,10 +42,12 @@ import Text.Parsec.Pos hiding (Line)
|
||||||
import qualified Text.Pandoc.UTF8 as UTF8
|
import qualified Text.Pandoc.UTF8 as UTF8
|
||||||
import System.Exit (exitWith, ExitCode(..))
|
import System.Exit (exitWith, ExitCode(..))
|
||||||
import System.IO (stderr)
|
import System.IO (stderr)
|
||||||
|
import Network.HTTP.Client (HttpException)
|
||||||
|
|
||||||
type Input = String
|
type Input = String
|
||||||
|
|
||||||
data PandocError = PandocIOError String IOError
|
data PandocError = PandocIOError String IOError
|
||||||
|
| PandocHttpError String HttpException
|
||||||
| PandocShouldNeverHappenError String
|
| PandocShouldNeverHappenError String
|
||||||
| PandocSomeError String
|
| PandocSomeError String
|
||||||
| PandocParseError String
|
| PandocParseError String
|
||||||
|
@ -70,6 +72,8 @@ handleError (Right r) = return r
|
||||||
handleError (Left e) =
|
handleError (Left e) =
|
||||||
case e of
|
case e of
|
||||||
PandocIOError _ err' -> ioError err'
|
PandocIOError _ err' -> ioError err'
|
||||||
|
PandocHttpError u err' -> err 61 $
|
||||||
|
"Could not fetch " ++ u ++ "\n" ++ show err'
|
||||||
PandocShouldNeverHappenError s -> err 62 s
|
PandocShouldNeverHappenError s -> err 62 s
|
||||||
PandocSomeError s -> err 63 s
|
PandocSomeError s -> err 63 s
|
||||||
PandocParseError s -> err 64 s
|
PandocParseError s -> err 64 s
|
||||||
|
|
|
@ -141,7 +141,8 @@ import Text.Pandoc.Data (dataFiles)
|
||||||
import Paths_pandoc (getDataFileName)
|
import Paths_pandoc (getDataFileName)
|
||||||
#endif
|
#endif
|
||||||
import Network.HTTP.Client (httpLbs, responseBody, responseHeaders,
|
import Network.HTTP.Client (httpLbs, responseBody, responseHeaders,
|
||||||
Request(port,host,requestHeaders))
|
Request(port,host,requestHeaders),
|
||||||
|
HttpException)
|
||||||
import Network.HTTP.Client (parseRequest)
|
import Network.HTTP.Client (parseRequest)
|
||||||
import Network.HTTP.Client (newManager)
|
import Network.HTTP.Client (newManager)
|
||||||
import Network.HTTP.Client.Internal (addProxy)
|
import Network.HTTP.Client.Internal (addProxy)
|
||||||
|
@ -702,13 +703,13 @@ readDataFileUTF8 userDir fname =
|
||||||
UTF8.toString `fmap` readDataFile userDir fname
|
UTF8.toString `fmap` readDataFile userDir fname
|
||||||
|
|
||||||
-- | Read from a URL and return raw data and maybe mime type.
|
-- | Read from a URL and return raw data and maybe mime type.
|
||||||
openURL :: String -> IO (BS.ByteString, Maybe MimeType)
|
openURL :: String -> IO (Either HttpException (BS.ByteString, Maybe MimeType))
|
||||||
openURL u
|
openURL u
|
||||||
| Just u'' <- stripPrefix "data:" u =
|
| Just u'' <- stripPrefix "data:" u =
|
||||||
let mime = takeWhile (/=',') u''
|
let mime = takeWhile (/=',') u''
|
||||||
contents = B8.pack $ unEscapeString $ drop 1 $ dropWhile (/=',') u''
|
contents = B8.pack $ unEscapeString $ drop 1 $ dropWhile (/=',') u''
|
||||||
in return (decodeLenient contents, Just mime)
|
in return $ Right (decodeLenient contents, Just mime)
|
||||||
| otherwise = withSocketsDo $ do
|
| otherwise = E.try $ withSocketsDo $ do
|
||||||
let parseReq = parseRequest
|
let parseReq = parseRequest
|
||||||
(proxy :: Either IOError String) <-
|
(proxy :: Either IOError String) <-
|
||||||
tryIOError $ getEnv "http_proxy"
|
tryIOError $ getEnv "http_proxy"
|
||||||
|
|
Loading…
Add table
Reference in a new issue