elm-pages 3.0.0-beta.14 → 3.0.0-beta.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/codegen/elm-pages-codegen.js +66 -118
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateData.elmo +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateDataTest.elmo +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Runner.elm.js +20 -20
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_supervisor.js +1 -1
- package/generator/dead-code-review/src/Pages/Review/DeadCodeEliminateData.elm +5 -5
- package/generator/dead-code-review/tests/Pages/Review/DeadCodeEliminateDataTest.elm +21 -21
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
- package/generator/review/elm-stuff/tests-0.19.1/js/node_supervisor.js +1 -1
- package/generator/src/RouteBuilder.elm +23 -23
- package/generator/src/SharedTemplate.elm +2 -2
- package/generator/src/SiteConfig.elm +2 -2
- package/generator/src/cli.js +2 -2
- package/generator/src/compatibility-key.js +1 -1
- package/generator/src/error-formatter.js +7 -3
- package/generator/src/render.js +6 -15
- package/generator/src/request-cache.js +34 -4
- package/generator/static-code/hmr.js +16 -2
- package/package.json +1 -1
- package/src/ApiRoute.elm +13 -16
- package/src/BackendTask/Env.elm +11 -8
- package/src/BackendTask/File.elm +49 -10
- package/src/BackendTask/Glob.elm +6 -6
- package/src/BackendTask/Http.elm +49 -13
- package/src/BackendTask/Port.elm +59 -47
- package/src/BackendTask.elm +8 -22
- package/src/FatalError.elm +101 -0
- package/src/Form.elm +3 -2
- package/src/Internal/ApiRoute.elm +5 -5
- package/src/Pages/Generate.elm +300 -103
- package/src/Pages/Internal/FatalError.elm +5 -0
- package/src/Pages/Internal/Platform/Cli.elm +21 -41
- package/src/Pages/Internal/Platform/CompatibilityKey.elm +1 -1
- package/src/Pages/Internal/Platform/GeneratorApplication.elm +24 -48
- package/src/Pages/Internal/Platform/StaticResponses.elm +18 -31
- package/src/Pages/Internal/Script.elm +2 -2
- package/src/Pages/Manifest.elm +2 -2
- package/src/Pages/ProgramConfig.elm +7 -7
- package/src/Pages/Script.elm +4 -4
- package/src/Pages/SiteConfig.elm +2 -2
- package/src/Pages/StaticHttpRequest.elm +1 -23
- package/src/Server/Request.elm +3 -2
- package/src/Exception.elm +0 -37
- package/src/MultiDict.elm +0 -49
- package/src/PairingHeap.elm +0 -137
- package/src/Parser/Extra/String.elm +0 -33
- package/src/Parser/Extra.elm +0 -69
- package/src/ProgramTest/ComplexQuery.elm +0 -360
- package/src/ProgramTest/EffectSimulation.elm +0 -122
- package/src/ProgramTest/Failure.elm +0 -367
- package/src/ProgramTest/HtmlHighlighter.elm +0 -116
- package/src/ProgramTest/HtmlParserHacks.elm +0 -58
- package/src/ProgramTest/HtmlRenderer.elm +0 -73
- package/src/ProgramTest/Program.elm +0 -30
- package/src/ProgramTest/StringLines.elm +0 -26
- package/src/ProgramTest/TestHtmlHacks.elm +0 -132
- package/src/ProgramTest/TestHtmlParser.elm +0 -201
- package/src/ProgramTest.elm +0 -2339
- package/src/Query/Extra.elm +0 -55
- package/src/SimulatedEffect/Cmd.elm +0 -69
- package/src/SimulatedEffect/Http.elm +0 -330
- package/src/SimulatedEffect/Navigation.elm +0 -69
- package/src/SimulatedEffect/Ports.elm +0 -62
- package/src/SimulatedEffect/Process.elm +0 -24
- package/src/SimulatedEffect/Sub.elm +0 -48
- package/src/SimulatedEffect/Task.elm +0 -252
- package/src/SimulatedEffect/Time.elm +0 -25
- package/src/SimulatedEffect.elm +0 -42
- package/src/String/Extra.elm +0 -6
- package/src/Test/Http.elm +0 -145
- package/src/TestResult.elm +0 -35
- package/src/TestState.elm +0 -305
- package/src/Url/Extra.elm +0 -100
- package/src/Vendored/Diff.elm +0 -321
- package/src/Vendored/Failure.elm +0 -217
- package/src/Vendored/FormatMonochrome.elm +0 -44
- package/src/Vendored/Highlightable.elm +0 -53
package/src/BackendTask/Port.elm
CHANGED
|
@@ -3,47 +3,36 @@ module BackendTask.Port exposing
|
|
|
3
3
|
, Error(..)
|
|
4
4
|
)
|
|
5
5
|
|
|
6
|
-
{-|
|
|
7
|
-
|
|
8
|
-
@docs get
|
|
9
|
-
|
|
10
|
-
@docs Error
|
|
11
|
-
|
|
12
|
-
-}
|
|
13
|
-
|
|
14
|
-
import BackendTask
|
|
15
|
-
import BackendTask.Http
|
|
16
|
-
import BackendTask.Internal.Request
|
|
17
|
-
import Exception exposing (Catchable)
|
|
18
|
-
import Json.Decode as Decode exposing (Decoder)
|
|
19
|
-
import Json.Encode as Encode
|
|
20
|
-
import TerminalText
|
|
6
|
+
{-| In a vanilla Elm application, ports let you either send or receive JSON data between your Elm application and the JavaScript context in the user's browser at runtime.
|
|
21
7
|
|
|
8
|
+
With `BackendTask.Port`, you send and receive JSON to JavaScript running in NodeJS. As with any `BackendTask`, Port BackendTask's are either run at build-time (for pre-rendered routes) or at request-time (for server-rendered routes). See [`BackendTask`](BackendTask) for more about the
|
|
9
|
+
lifecycle of `BackendTask`'s.
|
|
22
10
|
|
|
23
|
-
|
|
11
|
+
This means that you can call shell scripts, run NPM packages that are installed, or anything else you could do with NodeJS to perform custom side-effects, get some data, or both.
|
|
24
12
|
|
|
25
|
-
|
|
13
|
+
A `BackendTask.Port` will call an async JavaScript function with the given name from the definition in a file called `port-data-source.js` in your project's root directory. The function receives the input JSON value, and the Decoder is used to decode the return value of the async function.
|
|
26
14
|
|
|
27
|
-
|
|
15
|
+
@docs get
|
|
28
16
|
|
|
29
|
-
Here is the Elm code and corresponding JavaScript definition for getting an environment variable (or
|
|
17
|
+
Here is the Elm code and corresponding JavaScript definition for getting an environment variable (or an `FatalError BackendTask.Port.Error` if it isn't found). In this example,
|
|
18
|
+
we're using `BackendTask.allowFatal` to let the framework treat that as an unexpected exception, but we could also handle the possible failures of the `FatalError` (see [`FatalError`](FatalError)).
|
|
30
19
|
|
|
31
20
|
import BackendTask exposing (BackendTask)
|
|
32
21
|
import BackendTask.Port
|
|
33
22
|
import Json.Encode
|
|
34
23
|
import OptimizedDecoder as Decode
|
|
35
24
|
|
|
36
|
-
data : BackendTask String
|
|
25
|
+
data : BackendTask FatalError String
|
|
37
26
|
data =
|
|
38
27
|
BackendTask.Port.get "environmentVariable"
|
|
39
28
|
(Json.Encode.string "EDITOR")
|
|
40
29
|
Decode.string
|
|
30
|
+
|> BackendTask.allowFatal
|
|
41
31
|
|
|
42
32
|
-- will resolve to "VIM" if you run `EDITOR=vim elm-pages dev`
|
|
43
33
|
|
|
44
34
|
```javascript
|
|
45
|
-
|
|
46
|
-
|
|
35
|
+
// port-data-source.js
|
|
47
36
|
|
|
48
37
|
module.exports =
|
|
49
38
|
/**
|
|
@@ -56,32 +45,51 @@ module.exports =
|
|
|
56
45
|
if (result) {
|
|
57
46
|
return result;
|
|
58
47
|
} else {
|
|
59
|
-
throw `No environment variable called ${
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
48
|
+
throw `No environment variable called ${name}
|
|
49
|
+
|
|
50
|
+
Available:
|
|
51
|
+
|
|
52
|
+
${Object.keys(process.env).join("\n")}
|
|
53
|
+
`;
|
|
64
54
|
}
|
|
65
55
|
},
|
|
66
56
|
}
|
|
67
57
|
```
|
|
68
58
|
|
|
69
59
|
|
|
70
|
-
##
|
|
60
|
+
## Performance
|
|
71
61
|
|
|
72
|
-
`
|
|
62
|
+
As with any JavaScript or NodeJS code, avoid doing blocking IO operations. For example, avoid using `fs.readFileSync`, because blocking IO can slow down your elm-pages builds and dev server. `elm-pages` performances all `BackendTask`'s in parallel whenever possible.
|
|
63
|
+
So if you do `BackendTask.map2 Tuple.pair myHttpBackendTask myPortBackendTask`, it will resolve those two in parallel. NodeJS performs best when you take advantage of its ability to do non-blocking I/O (file reads, HTTP requests, etc.). If you use `BackendTask.andThen`,
|
|
64
|
+
it will need to resolve them in sequence rather than in parallel, but it's still best to avoid blocking IO operations in your BackendTask Port definitions.
|
|
73
65
|
|
|
74
|
-
Any time you throw an exception from a BackendTask.Port definition, it will result in a build error in your `elm-pages build` or dev server. In the example above, if the environment variable
|
|
75
|
-
is not found it will result in a build failure. Notice that the NPM package `kleur` is being used in this example to add color to the output for that build error. You can use any tool you
|
|
76
|
-
prefer to add ANSI color codes within the error string in an exception and it will show up with color output in the build output and dev server.
|
|
77
66
|
|
|
67
|
+
## Error Handling
|
|
78
68
|
|
|
79
|
-
|
|
69
|
+
There are a few different things that can go wrong when running a port-data-source. These possible errors are captured in the `BackendTask.Port.Error` type.
|
|
70
|
+
|
|
71
|
+
@docs Error
|
|
80
72
|
|
|
81
|
-
|
|
73
|
+
Any time you throw a JavaScript exception from a BackendTask.Port definition, it will give you a `PortCallException`. It's usually easier to add a `try`/`catch` in your JavaScript code in `port-data-source.js`
|
|
74
|
+
to handle possible errors, but you can throw a JSON value and handle it in Elm in the `PortCallException` call error.
|
|
82
75
|
|
|
83
76
|
-}
|
|
84
|
-
|
|
77
|
+
|
|
78
|
+
import BackendTask
|
|
79
|
+
import BackendTask.Http
|
|
80
|
+
import BackendTask.Internal.Request
|
|
81
|
+
import FatalError exposing (FatalError, Recoverable)
|
|
82
|
+
import Json.Decode as Decode exposing (Decoder)
|
|
83
|
+
import Json.Encode as Encode
|
|
84
|
+
import TerminalText
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
{-| -}
|
|
88
|
+
get :
|
|
89
|
+
String
|
|
90
|
+
-> Encode.Value
|
|
91
|
+
-> Decoder b
|
|
92
|
+
-> BackendTask.BackendTask { fatal : FatalError, recoverable : Error } b
|
|
85
93
|
get portName input decoder =
|
|
86
94
|
BackendTask.Internal.Request.request
|
|
87
95
|
{ name = "port"
|
|
@@ -97,7 +105,7 @@ get portName input decoder =
|
|
|
97
105
|
|> Decode.andThen
|
|
98
106
|
(\errorKind ->
|
|
99
107
|
if errorKind == "PortNotDefined" then
|
|
100
|
-
|
|
108
|
+
FatalError.recoverable
|
|
101
109
|
{ title = "Port Error"
|
|
102
110
|
, body =
|
|
103
111
|
[ TerminalText.text "Something went wrong in a call to BackendTask.Port.get. I expected to find a port named `"
|
|
@@ -106,6 +114,7 @@ get portName input decoder =
|
|
|
106
114
|
]
|
|
107
115
|
|> TerminalText.toString
|
|
108
116
|
}
|
|
117
|
+
(PortNotDefined { name = portName })
|
|
109
118
|
|> Decode.succeed
|
|
110
119
|
|
|
111
120
|
else if errorKind == "ExportIsNotFunction" then
|
|
@@ -114,7 +123,7 @@ get portName input decoder =
|
|
|
114
123
|
|> Decode.map (Maybe.withDefault "")
|
|
115
124
|
|> Decode.map
|
|
116
125
|
(\incorrectPortType ->
|
|
117
|
-
|
|
126
|
+
FatalError.recoverable
|
|
118
127
|
{ title = "Port Error"
|
|
119
128
|
, body =
|
|
120
129
|
[ TerminalText.text "Something went wrong in a call to BackendTask.Port.get. I found an export called `"
|
|
@@ -124,16 +133,18 @@ get portName input decoder =
|
|
|
124
133
|
]
|
|
125
134
|
|> TerminalText.toString
|
|
126
135
|
}
|
|
136
|
+
ExportIsNotFunction
|
|
127
137
|
)
|
|
128
138
|
|
|
129
139
|
else if errorKind == "MissingPortsFile" then
|
|
130
|
-
|
|
140
|
+
FatalError.recoverable
|
|
131
141
|
{ title = "Port Error"
|
|
132
142
|
, body =
|
|
133
143
|
[ TerminalText.text "Something went wrong in a call to BackendTask.Port.get. I couldn't find your port-data-source file. Be sure to create a 'port-data-source.ts' or 'port-data-source.js' file."
|
|
134
144
|
]
|
|
135
145
|
|> TerminalText.toString
|
|
136
146
|
}
|
|
147
|
+
MissingPortsFile
|
|
137
148
|
|> Decode.succeed
|
|
138
149
|
|
|
139
150
|
else if errorKind == "ErrorInPortsFile" then
|
|
@@ -142,8 +153,7 @@ get portName input decoder =
|
|
|
142
153
|
|> Decode.map (Maybe.withDefault "")
|
|
143
154
|
|> Decode.map
|
|
144
155
|
(\errorMessage ->
|
|
145
|
-
|
|
146
|
-
ErrorInPortsFile
|
|
156
|
+
FatalError.recoverable
|
|
147
157
|
{ title = "Port Error"
|
|
148
158
|
, body =
|
|
149
159
|
[ TerminalText.text "Something went wrong in a call to BackendTask.Port.get. I couldn't import the port definitions file, because of this exception:\n\n"
|
|
@@ -152,28 +162,29 @@ get portName input decoder =
|
|
|
152
162
|
]
|
|
153
163
|
|> TerminalText.toString
|
|
154
164
|
}
|
|
165
|
+
ErrorInPortsFile
|
|
155
166
|
)
|
|
156
167
|
|
|
157
|
-
else if errorKind == "
|
|
168
|
+
else if errorKind == "PortCallException" then
|
|
158
169
|
Decode.field "error" Decode.value
|
|
159
170
|
|> Decode.maybe
|
|
160
171
|
|> Decode.map (Maybe.withDefault Encode.null)
|
|
161
172
|
|> Decode.map
|
|
162
173
|
(\portCallError ->
|
|
163
|
-
|
|
164
|
-
(PortCallError portCallError)
|
|
174
|
+
FatalError.recoverable
|
|
165
175
|
{ title = "Port Error"
|
|
166
176
|
, body =
|
|
167
|
-
[ TerminalText.text "Something went wrong in a call to BackendTask.Port.get. I
|
|
177
|
+
[ TerminalText.text "Something went wrong in a call to BackendTask.Port.get. I was able to import the port definitions file, but when running it I encountered this exception:\n\n"
|
|
168
178
|
, TerminalText.red (Encode.encode 2 portCallError)
|
|
169
|
-
, TerminalText.text "\n\
|
|
179
|
+
, TerminalText.text "\n\nYou could add a `try`/`catch` in your `port-data-source` JavaScript code to handle that error."
|
|
170
180
|
]
|
|
171
181
|
|> TerminalText.toString
|
|
172
182
|
}
|
|
183
|
+
(PortCallException portCallError)
|
|
173
184
|
)
|
|
174
185
|
|
|
175
186
|
else
|
|
176
|
-
|
|
187
|
+
FatalError.recoverable
|
|
177
188
|
{ title = "Port Error"
|
|
178
189
|
, body =
|
|
179
190
|
[ TerminalText.text "Something went wrong in a call to BackendTask.Port.get. I expected to find a port named `"
|
|
@@ -182,6 +193,7 @@ get portName input decoder =
|
|
|
182
193
|
]
|
|
183
194
|
|> TerminalText.toString
|
|
184
195
|
}
|
|
196
|
+
ErrorInPortsFile
|
|
185
197
|
|> Decode.succeed
|
|
186
198
|
)
|
|
187
199
|
|> Decode.map Err
|
|
@@ -198,5 +210,5 @@ type Error
|
|
|
198
210
|
| ErrorInPortsFile
|
|
199
211
|
| MissingPortsFile
|
|
200
212
|
| PortNotDefined { name : String }
|
|
201
|
-
|
|
|
213
|
+
| PortCallException Decode.Value
|
|
202
214
|
| ExportIsNotFunction
|
package/src/BackendTask.elm
CHANGED
|
@@ -5,7 +5,7 @@ module BackendTask exposing
|
|
|
5
5
|
, andThen, resolve, combine
|
|
6
6
|
, andMap
|
|
7
7
|
, map2, map3, map4, map5, map6, map7, map8, map9
|
|
8
|
-
,
|
|
8
|
+
, allowFatal, mapError, onError, toResult
|
|
9
9
|
)
|
|
10
10
|
|
|
11
11
|
{-| In an `elm-pages` app, each Route Module can define a value `data` which is a `BackendTask` that will be resolved **before** `init` is called. That means it is also available
|
|
@@ -80,13 +80,13 @@ Any place in your `elm-pages` app where the framework lets you pass in a value o
|
|
|
80
80
|
@docs map2, map3, map4, map5, map6, map7, map8, map9
|
|
81
81
|
|
|
82
82
|
|
|
83
|
-
##
|
|
83
|
+
## FatalError Handling
|
|
84
84
|
|
|
85
|
-
@docs
|
|
85
|
+
@docs allowFatal, mapError, onError, toResult
|
|
86
86
|
|
|
87
87
|
-}
|
|
88
88
|
|
|
89
|
-
import
|
|
89
|
+
import FatalError exposing (FatalError)
|
|
90
90
|
import Json.Encode
|
|
91
91
|
import Pages.StaticHttpRequest exposing (RawRequest(..))
|
|
92
92
|
|
|
@@ -524,28 +524,14 @@ map9 combineFn request1 request2 request3 request4 request5 request6 request7 re
|
|
|
524
524
|
|
|
525
525
|
|
|
526
526
|
{-| -}
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|> onError
|
|
531
|
-
(\exception ->
|
|
532
|
-
case exception of
|
|
533
|
-
Catchable error _ ->
|
|
534
|
-
fail error
|
|
535
|
-
)
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
{-| -}
|
|
539
|
-
throw : BackendTask (Catchable error) data -> BackendTask Throwable data
|
|
540
|
-
throw backendTask =
|
|
541
|
-
backendTask
|
|
542
|
-
|> onError (Exception.throw >> fail)
|
|
527
|
+
allowFatal : BackendTask { error | fatal : FatalError } data -> BackendTask FatalError data
|
|
528
|
+
allowFatal backendTask =
|
|
529
|
+
mapError .fatal backendTask
|
|
543
530
|
|
|
544
531
|
|
|
545
532
|
{-| -}
|
|
546
|
-
toResult : BackendTask
|
|
533
|
+
toResult : BackendTask error data -> BackendTask noError (Result error data)
|
|
547
534
|
toResult backendTask =
|
|
548
535
|
backendTask
|
|
549
|
-
|> catch
|
|
550
536
|
|> andThen (Ok >> succeed)
|
|
551
537
|
|> onError (Err >> succeed)
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
module FatalError exposing
|
|
2
|
+
( FatalError, fromString, recoverable
|
|
3
|
+
, Recoverable
|
|
4
|
+
)
|
|
5
|
+
|
|
6
|
+
{-| The Elm language doesn't have the concept of exceptions or special control flow for errors. It just has
|
|
7
|
+
Custom Types, and by convention types like `Result` and the `Err` variant are used to represent possible failure states
|
|
8
|
+
and combine together different error states.
|
|
9
|
+
|
|
10
|
+
`elm-pages` doesn't change that, Elm still doesn't have special exception control flow at the language level. It does have
|
|
11
|
+
a type, which is just a regular old Elm type, called `FatalError`. Why? Because this plain old Elm type does have one
|
|
12
|
+
special characteristic - the `elm-pages` framework knows how to turn it into an error message. This becomes interesting
|
|
13
|
+
because an `elm-pages` app has several places that accept a value of type `BackendTask FatalError.FatalError value`.
|
|
14
|
+
This design lets the `elm-pages` framework do some of the work for you.
|
|
15
|
+
|
|
16
|
+
For example, if you wanted to handle possible errors to present them to the user
|
|
17
|
+
|
|
18
|
+
type alias Data =
|
|
19
|
+
String
|
|
20
|
+
|
|
21
|
+
data : RouteParams -> BackendTask FatalError Data
|
|
22
|
+
data routeParams =
|
|
23
|
+
BackendTask.Http.getJson "https://api.github.com/repos/dillonkearns/elm-pages"
|
|
24
|
+
(Decode.field "description" Decode.string)
|
|
25
|
+
|> BackendTask.onError
|
|
26
|
+
(\error ->
|
|
27
|
+
case FatalError.unwrap error of
|
|
28
|
+
BackendTask.Http.BadStatus metadata string ->
|
|
29
|
+
if metadata.statusCode == 401 || metadata.statusCode == 403 || metadata.statusCode == 404 then
|
|
30
|
+
BackendTask.succeed "Either this repo doesn't exist or you don't have access to it."
|
|
31
|
+
|
|
32
|
+
else
|
|
33
|
+
-- we're only handling these expected error cases. In the case of an HTTP timeout,
|
|
34
|
+
-- we'll let the error propagate as a FatalError
|
|
35
|
+
BackendTask.fail error |> BackendTask.allowFatal
|
|
36
|
+
|
|
37
|
+
_ ->
|
|
38
|
+
BackendTask.fail error |> BackendTask.allowFatal
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
This can be a lot of work for all possible errors, though. If you don't expect this kind of error (it's an _exceptional_ case),
|
|
42
|
+
you can let the framework handle it if the error ever does unexpectedly occur.
|
|
43
|
+
|
|
44
|
+
data : RouteParams -> BackendTask FatalError Data
|
|
45
|
+
data routeParams =
|
|
46
|
+
BackendTask.Http.getJson "https://api.github.com/repos/dillonkearns/elm-pages"
|
|
47
|
+
(Decode.field "description" Decode.string)
|
|
48
|
+
|> BackendTask.allowFatal
|
|
49
|
+
|
|
50
|
+
This is especially useful for pages generated at build-time (`RouteBuilder.preRender`) where you want the build
|
|
51
|
+
to fail if anything unexpected happens. With pre-rendered routes, you know that these error cases won't
|
|
52
|
+
be seen by users, so it's often a great idea to just let the framework handle these unexpected errors so a developer can
|
|
53
|
+
debug them and see what went wrong. In the example above, maybe we are only pre-rendering pages for a set of known
|
|
54
|
+
GitHub Repositories, so a Not Found or Unauthorized HTTP error would be unexpected and should stop the build so we can fix the
|
|
55
|
+
issue.
|
|
56
|
+
|
|
57
|
+
In the case of server-rendered Routes (`RouteBuilder.serverRender`), `elm-pages` will show your 500 error page
|
|
58
|
+
when these errors occur.
|
|
59
|
+
|
|
60
|
+
@docs FatalError, fromString, recoverable
|
|
61
|
+
|
|
62
|
+
@docs Recoverable
|
|
63
|
+
|
|
64
|
+
-}
|
|
65
|
+
|
|
66
|
+
import Pages.Internal.FatalError
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
{-| -}
|
|
70
|
+
type alias Recoverable error =
|
|
71
|
+
{ fatal : FatalError
|
|
72
|
+
, recoverable : error
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
{-| -}
|
|
77
|
+
type alias FatalError =
|
|
78
|
+
Pages.Internal.FatalError.FatalError
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
{-| -}
|
|
82
|
+
build : { title : String, body : String } -> FatalError
|
|
83
|
+
build info =
|
|
84
|
+
Pages.Internal.FatalError.FatalError info
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
{-| -}
|
|
88
|
+
fromString : String -> FatalError
|
|
89
|
+
fromString string =
|
|
90
|
+
build
|
|
91
|
+
{ title = "Custom Error"
|
|
92
|
+
, body = string
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
{-| -}
|
|
97
|
+
recoverable : { title : String, body : String } -> value -> Recoverable value
|
|
98
|
+
recoverable info value =
|
|
99
|
+
{ fatal = build info
|
|
100
|
+
, recoverable = value
|
|
101
|
+
}
|
package/src/Form.elm
CHANGED
|
@@ -269,6 +269,7 @@ Totally customizable. Uses [`Form.FieldView`](Form-FieldView) to render all of t
|
|
|
269
269
|
|
|
270
270
|
import BackendTask exposing (BackendTask)
|
|
271
271
|
import Dict exposing (Dict)
|
|
272
|
+
import FatalError exposing (FatalError)
|
|
272
273
|
import Form.Field as Field exposing (Field(..))
|
|
273
274
|
import Form.FieldStatus as FieldStatus exposing (FieldStatus)
|
|
274
275
|
import Form.FieldView
|
|
@@ -681,7 +682,7 @@ toServerForm :
|
|
|
681
682
|
->
|
|
682
683
|
Form
|
|
683
684
|
error
|
|
684
|
-
{ combine : Validation.Validation error (BackendTask
|
|
685
|
+
{ combine : Validation.Validation error (BackendTask FatalError (Validation.Validation error combined kind constraints)) kind constraints
|
|
685
686
|
, view : viewFn
|
|
686
687
|
}
|
|
687
688
|
data
|
|
@@ -694,7 +695,7 @@ toServerForm (Form a b c) =
|
|
|
694
695
|
{ result : Dict String (List error)
|
|
695
696
|
, isMatchCandidate : Bool
|
|
696
697
|
, combineAndView :
|
|
697
|
-
{ combine : Validation.Validation error (BackendTask
|
|
698
|
+
{ combine : Validation.Validation error (BackendTask FatalError (Validation.Validation error combined kind constraints)) kind constraints
|
|
698
699
|
, view : viewFn
|
|
699
700
|
}
|
|
700
701
|
}
|
|
@@ -9,7 +9,7 @@ module Internal.ApiRoute exposing
|
|
|
9
9
|
)
|
|
10
10
|
|
|
11
11
|
import BackendTask exposing (BackendTask)
|
|
12
|
-
import
|
|
12
|
+
import FatalError exposing (FatalError)
|
|
13
13
|
import Head
|
|
14
14
|
import Json.Decode
|
|
15
15
|
import Pattern exposing (Pattern)
|
|
@@ -46,12 +46,12 @@ tryMatchDone path (ApiRoute handler) =
|
|
|
46
46
|
type ApiRoute response
|
|
47
47
|
= ApiRoute
|
|
48
48
|
{ regex : Regex
|
|
49
|
-
, matchesToResponse : Json.Decode.Value -> String -> BackendTask
|
|
50
|
-
, buildTimeRoutes : BackendTask
|
|
51
|
-
, handleRoute : String -> BackendTask
|
|
49
|
+
, matchesToResponse : Json.Decode.Value -> String -> BackendTask FatalError (Maybe response)
|
|
50
|
+
, buildTimeRoutes : BackendTask FatalError (List String)
|
|
51
|
+
, handleRoute : String -> BackendTask FatalError Bool
|
|
52
52
|
, pattern : Pattern
|
|
53
53
|
, kind : String
|
|
54
|
-
, globalHeadTags : Maybe (BackendTask
|
|
54
|
+
, globalHeadTags : Maybe (BackendTask FatalError (List Head.Tag))
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
|