-
Notifications
You must be signed in to change notification settings - Fork 412
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Better error messages #462
Changes from 10 commits
2b87d13
8ac7949
9ec43a6
7031661
f98a220
0ec007e
458e78d
dd68b2e
f546381
7f1b00e
1e04f93
2f6ef3a
c098216
e523fb7
f6af7d4
e263ccf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,7 @@ module Hakyll.Core.Compiler.Internal | |
Snapshot | ||
, CompilerRead (..) | ||
, CompilerWrite (..) | ||
, Reason (..) | ||
, CompilerResult (..) | ||
, Compiler (..) | ||
, runCompiler | ||
|
@@ -17,11 +18,15 @@ module Hakyll.Core.Compiler.Internal | |
, compilerTell | ||
, compilerAsk | ||
, compilerThrow | ||
, compilerFailMessage | ||
, compilerTry | ||
, compilerCatch | ||
, compilerResult | ||
, compilerUnsafeIO | ||
, compilerDebugLog | ||
|
||
-- * Utilities | ||
, getReason | ||
, compilerTellDependencies | ||
, compilerTellCacheHits | ||
) where | ||
|
@@ -31,7 +36,7 @@ module Hakyll.Core.Compiler.Internal | |
import Control.Applicative (Alternative (..)) | ||
import Control.Exception (SomeException, handle) | ||
import Control.Monad (forM_) | ||
import Control.Monad.Except (MonadError (..)) | ||
import Control.Monad.Except (MonadError (..)) | ||
import Data.Set (Set) | ||
import qualified Data.Set as S | ||
|
||
|
@@ -41,7 +46,6 @@ import Hakyll.Core.Configuration | |
import Hakyll.Core.Dependencies | ||
import Hakyll.Core.Identifier | ||
import Hakyll.Core.Identifier.Pattern | ||
import Hakyll.Core.Logger (Logger) | ||
import qualified Hakyll.Core.Logger as Logger | ||
import Hakyll.Core.Metadata | ||
import Hakyll.Core.Provider | ||
|
@@ -71,7 +75,7 @@ data CompilerRead = CompilerRead | |
, -- | Compiler store | ||
compilerStore :: Store | ||
, -- | Logger | ||
compilerLogger :: Logger | ||
compilerLogger :: Logger.Logger | ||
} | ||
|
||
|
||
|
@@ -89,11 +93,25 @@ instance Monoid CompilerWrite where | |
CompilerWrite (d1 ++ d2) (h1 + h2) | ||
|
||
|
||
-------------------------------------------------------------------------------- | ||
data Reason a | ||
-- | An exception occured during compilation | ||
= CompilationFailure a | ||
-- | Absence of any result, most notably in template contexts | ||
| NoCompilationResult a | ||
|
||
|
||
-- | Unwrap a `Reason` | ||
getReason :: Reason a -> a | ||
getReason (CompilationFailure x) = x | ||
getReason (NoCompilationResult x) = x | ||
|
||
|
||
-------------------------------------------------------------------------------- | ||
data CompilerResult a where | ||
CompilerDone :: a -> CompilerWrite -> CompilerResult a | ||
CompilerSnapshot :: Snapshot -> Compiler a -> CompilerResult a | ||
CompilerError :: [String] -> CompilerResult a | ||
CompilerError :: Reason [String] -> CompilerResult a | ||
CompilerRequire :: (Identifier, Snapshot) -> Compiler a -> CompilerResult a | ||
|
||
|
||
|
@@ -112,8 +130,8 @@ instance Functor Compiler where | |
return $ case res of | ||
CompilerDone x w -> CompilerDone (f x) w | ||
CompilerSnapshot s c' -> CompilerSnapshot s (fmap f c') | ||
CompilerError e -> CompilerError e | ||
CompilerRequire i c' -> CompilerRequire i (fmap f c') | ||
CompilerError e -> CompilerError e | ||
{-# INLINE fmap #-} | ||
|
||
|
||
|
@@ -132,14 +150,14 @@ instance Monad Compiler where | |
CompilerSnapshot s c' -> CompilerSnapshot s $ do | ||
compilerTell w -- Save dependencies! | ||
c' | ||
CompilerError e -> CompilerError e | ||
CompilerRequire i c' -> CompilerRequire i $ do | ||
compilerTell w -- Save dependencies! | ||
c' | ||
CompilerError e -> CompilerError e | ||
|
||
CompilerSnapshot s c' -> return $ CompilerSnapshot s (c' >>= f) | ||
CompilerError e -> return $ CompilerError e | ||
CompilerRequire i c' -> return $ CompilerRequire i (c' >>= f) | ||
CompilerError e -> return $ CompilerError e | ||
{-# INLINE (>>=) #-} | ||
|
||
fail = compilerThrow . return | ||
|
@@ -164,25 +182,30 @@ instance MonadMetadata Compiler where | |
-------------------------------------------------------------------------------- | ||
instance MonadError [String] Compiler where | ||
throwError = compilerThrow | ||
catchError = compilerCatch | ||
catchError c = compilerCatch c . (. getReason) | ||
|
||
|
||
-------------------------------------------------------------------------------- | ||
runCompiler :: Compiler a -> CompilerRead -> IO (CompilerResult a) | ||
runCompiler compiler read' = handle handler $ unCompiler compiler read' | ||
where | ||
handler :: SomeException -> IO (CompilerResult a) | ||
handler e = return $ CompilerError [show e] | ||
handler e = return $ CompilerError $ CompilationFailure [show e] | ||
|
||
|
||
-------------------------------------------------------------------------------- | ||
instance Alternative Compiler where | ||
empty = compilerThrow [] | ||
x <|> y = compilerCatch x $ \es -> do | ||
logger <- compilerLogger <$> compilerAsk | ||
forM_ es $ \e -> compilerUnsafeIO $ Logger.debug logger $ | ||
"Hakyll.Core.Compiler.Internal: Alternative failed: " ++ e | ||
y | ||
empty = compilerMissing [] | ||
x <|> y = x `compilerCatch` (\rx -> y `compilerCatch` (\ry -> | ||
case (rx, ry) of | ||
(CompilationFailure xs, CompilationFailure ys) -> compilerThrow $ xs ++ ys | ||
(CompilationFailure xs, NoCompilationResult ys) -> debug ys >> compilerThrow xs | ||
(NoCompilationResult xs, CompilationFailure ys) -> debug xs >> compilerThrow ys | ||
(NoCompilationResult xs, NoCompilationResult ys) -> compilerMissing $ xs ++ ys | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I could have made |
||
)) | ||
where | ||
debug = compilerDebugLog . map | ||
("Hakyll.Core.Compiler.Internal: Alternative fail suppressed: " ++) | ||
{-# INLINE (<|>) #-} | ||
|
||
|
||
|
@@ -194,49 +217,70 @@ compilerAsk = Compiler $ \r -> return $ CompilerDone r mempty | |
|
||
-------------------------------------------------------------------------------- | ||
compilerTell :: CompilerWrite -> Compiler () | ||
compilerTell deps = Compiler $ \_ -> return $ CompilerDone () deps | ||
compilerTell = compilerResult . CompilerDone () | ||
{-# INLINE compilerTell #-} | ||
|
||
|
||
-------------------------------------------------------------------------------- | ||
-- | Put the result back in a compiler | ||
compilerResult :: CompilerResult a -> Compiler a | ||
compilerResult x = Compiler $ \_ -> return x | ||
{-# INLINE compilerResult #-} | ||
|
||
|
||
-------------------------------------------------------------------------------- | ||
compilerThrow :: [String] -> Compiler a | ||
compilerThrow es = Compiler $ \_ -> return $ CompilerError es | ||
{-# INLINE compilerThrow #-} | ||
compilerThrow = compilerResult . CompilerError . CompilationFailure | ||
|
||
compilerMissing :: [String] -> Compiler a | ||
compilerMissing = compilerResult . CompilerError . NoCompilationResult | ||
|
||
compilerFailMessage :: String -> Compiler a | ||
compilerFailMessage = compilerMissing . return | ||
|
||
|
||
-------------------------------------------------------------------------------- | ||
compilerCatch :: Compiler a -> ([String] -> Compiler a) -> Compiler a | ||
compilerTry :: Compiler a -> Compiler (Either (Reason [String]) a) | ||
compilerTry (Compiler x) = Compiler $ \r -> do | ||
res <- x r | ||
case res of | ||
CompilerDone res' w -> return (CompilerDone (Right res') w) | ||
CompilerSnapshot s c -> return (CompilerSnapshot s (compilerTry c)) | ||
CompilerRequire i c -> return (CompilerRequire i (compilerTry c)) | ||
CompilerError e -> return (CompilerDone (Left e) mempty) | ||
{-# INLINE compilerTry #-} | ||
|
||
-------------------------------------------------------------------------------- | ||
-- compilerCatch f = compilerTry >=> either f return | ||
compilerCatch :: Compiler a -> (Reason [String] -> Compiler a) -> Compiler a | ||
compilerCatch (Compiler x) f = Compiler $ \r -> do | ||
res <- x r | ||
case res of | ||
CompilerDone res' w -> return (CompilerDone res' w) | ||
CompilerSnapshot s c -> return (CompilerSnapshot s (compilerCatch c f)) | ||
CompilerError e -> unCompiler (f e) r | ||
CompilerRequire i c -> return (CompilerRequire i (compilerCatch c f)) | ||
CompilerError e -> unCompiler (f e) r | ||
{-# INLINE compilerCatch #-} | ||
|
||
|
||
-------------------------------------------------------------------------------- | ||
-- | Put the result back in a compiler | ||
compilerResult :: CompilerResult a -> Compiler a | ||
compilerResult x = Compiler $ \_ -> return x | ||
{-# INLINE compilerResult #-} | ||
|
||
|
||
-------------------------------------------------------------------------------- | ||
compilerUnsafeIO :: IO a -> Compiler a | ||
compilerUnsafeIO io = Compiler $ \_ -> do | ||
x <- io | ||
return $ CompilerDone x mempty | ||
{-# INLINE compilerUnsafeIO #-} | ||
|
||
-------------------------------------------------------------------------------- | ||
compilerDebugLog :: [String] -> Compiler () | ||
compilerDebugLog ms = do | ||
logger <- compilerLogger <$> compilerAsk | ||
compilerUnsafeIO $ forM_ ms $ Logger.debug logger | ||
|
||
-------------------------------------------------------------------------------- | ||
compilerTellDependencies :: [Dependency] -> Compiler () | ||
compilerTellDependencies ds = do | ||
logger <- compilerLogger <$> compilerAsk | ||
forM_ ds $ \d -> compilerUnsafeIO $ Logger.debug logger $ | ||
"Hakyll.Core.Compiler.Internal: Adding dependency: " ++ show d | ||
compilerDebugLog $ map (\d -> | ||
"Hakyll.Core.Compiler.Internal: Adding dependency: " ++ show d) ds | ||
compilerTell mempty {compilerDependencies = ds} | ||
{-# INLINE compilerTellDependencies #-} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -140,14 +140,13 @@ | |
-- | ||
module Hakyll.Web.Template | ||
( Template | ||
, template | ||
, readTemplateElems | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This essentially reverts 526cd35. Instead of exposing those primitives, To benefit from error messages, I used the Btw, could There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, we should be good to rip out |
||
, templateBodyCompiler | ||
, templateCompiler | ||
, applyTemplate | ||
, loadAndApplyTemplate | ||
, applyAsTemplate | ||
, readTemplate | ||
, compileTemplateItem | ||
, unsafeReadTemplateFile | ||
) where | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess
unReason
might have followed the naming conventions, but it seemed kinda unreasonable :-DThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😁