scalpel 0.6.2.1 → 0.6.2.2
raw patch · 3 files changed
+87/−4 lines, 3 filesdep ~scalpel-corePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: scalpel-core
API changes (from Hackage documentation)
Files
- CHANGELOG.md +4/−0
- README.md +80/−1
- scalpel.cabal +3/−3
CHANGELOG.md view
@@ -2,6 +2,10 @@ ## HEAD +## 0.6.2.2++- Fix build breakage on GHC 9.8 / mtl 2.3+ ## 0.6.2.1 - Match Content-Type case-insensitively.
README.md view
@@ -1,4 +1,5 @@-Scalpel [](https://travis-ci.org/fimad/scalpel) [](https://hackage.haskell.org/package/scalpel)+Scalpel+[](https://github.com/fimad/scalpel/actions/workflows/stack.yml) [](https://hackage.haskell.org/package/scalpel) ======= Scalpel is a web scraping library inspired by libraries like@@ -278,6 +279,84 @@ [downloading data](https://github.com/fimad/scalpel/tree/master/examples/image-sizes/) For more documentation on monad transformers, see the [hackage page](https://hackage.haskell.org/package/transformers)++### Explicit error handling++`ScraperT` is an instance of `MonadError` which allows you to throw errors from+within parsing code to stop parsing and return an error.++When doing error handling in this way, there are 3 cases to consider:+ 1. An explicitly thrown error+ 2. A failed scraping without a thrown error+ 3. A valid result++This can be implemented for `String` valued errors as follows:++```+type Error = String+type ScraperWithError a = ScraperT String (Either Error) a++scrapeStringOrError :: String -> ScraperWithError a -> Either Error a+scrapeStringOrError html scraper+ | Left error <- result = Left error+ | Right Nothing <- result = Left "Unknown error"+ | Right (Just a) <- result = Right a+ where+ result = scrapeStringLikeT html scraper+```++To add explicit erroring you can use the <|> operator from Alternative to throw+an error when something fails:++```+comment :: ScraperWithError Comment+comment = textComment <|> imageComment <|> throwError "Unknown comment type"+```++With this approach, when you throw an error it will stop all parsing. So if you+have an expression `a <|> b` and there is a nested throwError in `a`, then the+parsing will fail. Even if `b` would be successful.++For the full source for this approach, see+[error-handling](https://github.com/fimad/scalpel/tree/master/examples/error-handling/)+in the examples directory.++Another approach that would let you accumulate errors without stopping parsing+would be to use `MonadWriter` and accumulate debugging information in a `Monoid`+like a list:++```+type Error = String+type ScraperWithError a = ScraperT String (Writer [Error]) a++scrapeStringOrError :: String -> ScraperWithError a -> (Maybe a, [Error])+scrapeStringOrError html scraper = runWriter . scrapeStringLikeT+```++Then to log an error you can use `tell`:++```+comment :: ScraperWithError Comment+comment = textComment <|> imageComment <|> (tell ["Unknown comment type"] >> empty)+```++You can also retrieve the current HTML being parsed with `html anySelector` and+incorporate that into your log message:++```+logError :: String -> ScraperWithError a+logError message = do+ currentHtml <- html anySelector+ tell ["Unknown comment type: " ++ html]+ empty++comment :: ScraperWithError Comment+comment = textComment <|> imageComment <|> logError "Unknown comment type: "+```++For the full source for this approach, see+[error-handling-with-writer](https://github.com/fimad/scalpel/tree/master/examples/error-handling-with-writer/)+in the examples directory. ### scalpel-core
scalpel.cabal view
@@ -1,5 +1,5 @@ name: scalpel-version: 0.6.2.1+version: 0.6.2.2 synopsis: A high level web scraping library for Haskell. description: Scalpel is a web scraping library inspired by libraries like Parsec and@@ -24,7 +24,7 @@ source-repository this type: git location: https://github.com/fimad/scalpel.git- tag: v0.6.2.1+ tag: v0.6.2.2 library other-extensions:@@ -38,7 +38,7 @@ default-language: Haskell2010 build-depends: base >= 4.6 && < 5- , scalpel-core == 0.6.2.1+ , scalpel-core == 0.6.2.2 , bytestring , case-insensitive , data-default