Skip to content

Commit 512669b

Browse files
authored
Better handling of parser errors; fixes #1 (#2)
* parser errors are so far generating Effects * detection working for firefox * adding more notes to get working with chromium; support multiple error NSes * correctly getting error in firefox but chrome error is empty string * devised a working error handling scheme for both firefox and chrome * fixed new API * adding some documentation
1 parent da71c02 commit 512669b

File tree

7 files changed

+138
-24
lines changed

7 files changed

+138
-24
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,6 @@ ehthumbs.db
2828
Thumbs.db
2929
.Trash*
3030
.history/
31+
32+
*~
33+
.#*

bower.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
"dependencies": {
2222
"purescript-prelude": "^4.1.0",
2323
"purescript-effect": "^2.0.1",
24-
"purescript-web-dom": "^2.0.0",
24+
"purescript-web-dom": "^3.0.0",
2525
"purescript-partial": "^2.0.1"
2626
},
2727
"devDependencies": {

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
"devDependencies": {
1313
"bower": "^1.8.6",
1414
"parcel-bundler": "^1.12.3",
15-
"pulp": "^12.4.0",
16-
"purescript": "^0.12.4",
15+
"pulp": "^13.0.0",
16+
"purescript": "^0.13.0",
1717
"purescript-psa": "~0.7.3",
1818
"rimraf": "^2.6.3"
1919
},

psc.sh

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#!/usr/bin/env bash
2+
3+
#
4+
# If you found this in a repository other than
5+
# purescript-hodgepodge, know that it was likely copied or modified
6+
# from the script of the same name located at
7+
# https://github.com/bbarker/purescript-hodgepodge
8+
#
9+
# You can find more information there about this script.
10+
#
11+
12+
13+
: "${IMG_NAME:=purescript-hodgepodge}"
14+
: "${IMG_VER:=latest}"
15+
# Set this to the empty string to use locally built image:
16+
if ! [[ -v "DHUB_PREFIX" ]]; then
17+
: "${DHUB_PREFIX:=bbarker/}"
18+
fi
19+
20+
# If really an empty string, then we interpret as using a local image
21+
# and do not pull:
22+
if ! [ -z "$DHUB_PREFIX" ]; then
23+
docker pull "${DHUB_PREFIX}${IMG_NAME}:${IMG_VER}"
24+
fi
25+
26+
# Make these directories so docker (root) does not!
27+
mkdir -p ~/.pulp
28+
mkdir -p ~/.npm
29+
mkdir -p ~/.npm-packages
30+
mkdir -p ~/.cache
31+
touch ~/.pulp/github-oauth-token
32+
33+
34+
docker run --rm -ti \
35+
--volume /etc/passwd:/etc/passwd:ro \
36+
--volume "$PWD":/wd \
37+
--volume "$HOME/.gitconfig:$HOME/.gitconfig:ro" \
38+
--volume "$HOME/.ssh:$HOME/.ssh:ro" \
39+
--volume "$HOME/.pulp:$HOME/.pulp" \
40+
--volume "$HOME/.cache:$HOME/.cache" \
41+
--volume "$HOME/.npmrc:$HOME/.npmrc" \
42+
--volume "$HOME/.npm:$HOME/.npm" \
43+
--volume "$HOME/.npm-packages:$HOME/.npm-packages" \
44+
--user "$UID" \
45+
--workdir /wd \
46+
-e "XDG_CONFIG_HOME=/wd/.xdg_config_home" \
47+
-e "XDG_DATA_HOME=/wd/.xdg_data_home" \
48+
"${DHUB_PREFIX}${IMG_NAME}:${IMG_VER}" "$@"
49+
50+
# Add this before the last line (image name) for debugging:
51+
# --entrypoint "/bin/bash" \

scripts/testbrowser

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22

33
npm run build && \
44
pulp build --main "Test.Main" --src-path "src" -I "test" \
5-
-- --censor-lib --strict && \
6-
parcel --no-hmr --public-url ./ build test/index.html
5+
-- --censor-lib && \
6+
parcel build --public-url ./ test/index.html

src/Web/DOM/DOMParser.purs

Lines changed: 49 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,35 +5,71 @@ module Web.DOM.DOMParser
55
, parseHTMLFromString
66
, parseSVGFromString
77
, parseXMLFromString
8+
, _getParserError
89
) where
910

10-
--import Prelude
11+
import Prelude (($), bind, join, map, pure)
1112

13+
import Data.Array (head)
14+
import Data.Either (Either(..))
15+
import Data.Maybe (Maybe(..))
1216
import Effect (Effect)
13-
import Web.DOM.Document (Document)
17+
import Web.DOM.Document (Document, getElementsByTagName)
18+
import Web.DOM.Element (Element, toNode)
19+
import Web.DOM.HTMLCollection (toArray)
20+
import Web.DOM.Node (textContent)
1421

1522
foreign import data DOMParserType
1623

1724
--| Create a new `DOMParser`
1825
foreign import makeDOMParser Effect DOMParser
1926

20-
--| Parse a string with the first argumet being a string for a doctype
21-
foreign import parseFromString String String DOMParser Effect Document
27+
--| Parse a string with the first argumet being a string for a doctype.
28+
--| Does not capture errors; consider using other wrapper functions,
29+
--| e.g. parseXMLFromString.
30+
foreign import parseFromString String -> String -> DOMParser -> Effect Document
2231

2332
--| Convience function to parse HTML from a string, partially applying
2433
--| `parseFromString` with "text/html"
25-
parseHTMLFromString String DOMParser Effect Document
26-
parseHTMLFromString s d =
27-
parseFromString "text/html" s d
34+
parseHTMLFromString String -> DOMParser -> Effect (Either String Document)
35+
parseHTMLFromString s d = do
36+
doc <- parseFromString "text/html" s d
37+
errMay <- _getParserError doc
38+
pure $ returnIfNothing errMay doc
2839

2940
--| Convience function to parse SVG from a string, partially applying
3041
--| `parseFromString` with "image/svg+xml"
31-
parseSVGFromString String DOMParser Effect Document
32-
parseSVGFromString s d =
33-
parseFromString "image/svg+xml" s d
42+
parseSVGFromString String -> DOMParser -> Effect (Either String Document)
43+
parseSVGFromString s d = do
44+
doc <- parseFromString "image/svg+xml" s d
45+
errMay <- _getParserError doc
46+
pure $ returnIfNothing errMay doc
3447

3548
--| Convience function to parse XML from a string, partially applying
3649
--| `parseFromString` with "application/xml"
37-
parseXMLFromString String DOMParser Effect Document
38-
parseXMLFromString s d =
39-
parseFromString "application/xml" s d
50+
parseXMLFromString String -> DOMParser -> Effect (Either String Document)
51+
parseXMLFromString s d = do
52+
doc <- parseFromString "application/xml" s d
53+
errMay <- _getParserError doc
54+
pure $ returnIfNothing errMay doc
55+
56+
--| Utility method for extracting Dom Parser errors from document;
57+
--| should only need to be used if calling `parseFromString` directly.
58+
_getParserError :: Document -> Effect (Maybe String)
59+
_getParserError doc = do
60+
peElems :: Array Element <- join $ map toArray $ getElementsByTagName "parsererror" doc
61+
peEleMay :: Maybe Element <- pure $ head $ peElems
62+
getText peEleMay
63+
where
64+
getText :: Maybe Element -> Effect (Maybe String)
65+
getText elMay = case map toNode elMay of
66+
Nothing -> pure $ Nothing
67+
Just nd -> map Just $ textContent nd
68+
69+
--| Like [Data.Either.note](https://pursuit.purescript.org/packages/purescript-either/docs/Data.Either#v:note),
70+
--| but with the logic reversed. Used internally for converting the
71+
--| result of `_getParserError` to an `Either`.
72+
returnIfNothing :: forall a b. Maybe a -> b -> Either a b
73+
returnIfNothing errMay val = case errMay of
74+
Nothing -> Right val
75+
Just er -> Left er

test/Main.purs

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,46 @@ module Test.Main where
22

33
import Prelude
44

5+
import Data.Either (Either, isLeft, isRight)
6+
import Data.Maybe (Maybe(..))
57
import Effect (Effect)
68
import Effect.Console (log)
79
import Test.Data as TD
810

911
import Web.DOM.Document (Document)
10-
import Web.DOM.DOMParser (DOMParser, makeDOMParser, parseXMLFromString)
12+
import Web.DOM.DOMParser (DOMParser, makeDOMParser, parseFromString,
13+
parseXMLFromString, _getParserError)
1114

12-
parseNoteDoc :: DOMParser -> Effect Document
15+
parseNoteDocRaw :: DOMParser -> Effect Document
16+
parseNoteDocRaw = parseFromString "application/xml" TD.noteXml
17+
parseNoteDoc :: DOMParser -> Effect (Either String Document)
1318
parseNoteDoc = parseXMLFromString TD.noteXml
1419

15-
-- parseGarbage :: DOMParser -> Effect Document
16-
-- parseGarbage dp = parseXMLFromString "`~~`lkjlj3424" dp
20+
parseGarbageRaw :: DOMParser -> Effect Document
21+
parseGarbageRaw = parseFromString "application/xml" "<foo>asdf<bar></foo>"
22+
parseGarbage :: DOMParser -> Effect (Either String Document)
23+
parseGarbage = parseXMLFromString "<foo>asdf<bar></foo>"
24+
1725

1826
main :: Effect Unit
1927
main = do
2028
domParser <- makeDOMParser
21-
note <- parseNoteDoc domParser
22-
-- garbageOut <- parseGarbage domParser
29+
note <- parseNoteDocRaw domParser
30+
parseNoErrMay <-_getParserError note
31+
case parseNoErrMay of
32+
Nothing -> log "no parse error found for garbageOut"
33+
Just er -> log $ "Error is:" <> er
34+
log "test0"
35+
garbageOut <- parseGarbageRaw domParser
36+
log "test1"
37+
parseErrMay <-_getParserError garbageOut
38+
case parseErrMay of
39+
Nothing -> log "no parse error found for garbageOut"
40+
Just er -> log $ "Error is:" <> er
41+
log "test 2"
42+
shouldBeRight <- parseNoteDoc domParser
43+
log $ "is Right? " <> show (isRight shouldBeRight)
44+
shouldBeLeft <- parseGarbage domParser
45+
log $ "is Left? " <> show (isLeft shouldBeLeft)
46+
2347
log "TODO: You should add some tests."

0 commit comments

Comments
 (0)