@jsenv/navi 0.29.53 → 0.29.55
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/dist/jsenv_navi.js +741 -169
- package/dist/jsenv_navi.js.map +57 -26
- package/docs/error_handling.md +44 -14
- package/package.json +1 -1
package/docs/error_handling.md
CHANGED
|
@@ -137,19 +137,35 @@ branch, `useAsyncData({ error: true })`
|
|
|
137
137
|
when it hands the error to the component, and a run given an `onError` — asking
|
|
138
138
|
for the error is taking it.
|
|
139
139
|
|
|
140
|
-
##
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
unhandled
|
|
144
|
-
code that produced
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
140
|
+
## Taken by nobody: the report
|
|
141
|
+
|
|
142
|
+
An error that no render ever read is re-thrown, which makes it an ordinary
|
|
143
|
+
unhandled error — window `error` event, jsenv overlay in dev — pointing at the
|
|
144
|
+
code that produced it.
|
|
145
|
+
|
|
146
|
+
**Being read is enough to call the report off**, displayed or not. Once a render
|
|
147
|
+
has the error, everything that can happen next is already covered without this
|
|
148
|
+
module: it is displayed (and marked), or it is thrown — and a thrown error either
|
|
149
|
+
finds a boundary that displays it, or reaches window on its own, since
|
|
150
|
+
`preact/debug` re-throws what a boundary caught and an unbounded throw aborts the
|
|
151
|
+
render loudly. Reporting it here too would be a second voice, and the wrong one:
|
|
152
|
+
this module cannot see which of those happened.
|
|
153
|
+
|
|
154
|
+
So what reaches the report is an error **nothing looked at** — an action nobody
|
|
155
|
+
reads, a prerun for a page never opened. And _when_ it is reported follows from
|
|
156
|
+
that:
|
|
157
|
+
|
|
158
|
+
- one macrotask, because every render that could read it happens in microtasks;
|
|
159
|
+
- but a route action fails ON the url change, before its page exists — it is the
|
|
160
|
+
routing itself that brings what will display the error. So the deadline waits
|
|
161
|
+
for the document to stop moving and for the frame that paints what the routing
|
|
162
|
+
brought. Anything faster tells an app that is displaying "you are offline" that
|
|
163
|
+
it displayed nothing (measured: the screen arrived ~12ms after a plain
|
|
164
|
+
macrotask deadline).
|
|
165
|
+
|
|
166
|
+
Waiting longer costs nothing, precisely because a read is enough to call it off:
|
|
167
|
+
what is still unread by then was going to stay unread. The same error reaching
|
|
168
|
+
the report twice is reported once.
|
|
153
169
|
|
|
154
170
|
## Writing your own boundary
|
|
155
171
|
|
|
@@ -171,4 +187,18 @@ The one reason to write your own: **filtering what you take.** navi's takes
|
|
|
171
187
|
everything its subtree throws. An app that wants its own bugs to stay visible
|
|
172
188
|
displays only what is data to it — an error carrying an HTTP status, its own
|
|
173
189
|
`OfflineError` — and re-throws the rest **unmarked**, so the overlay still does
|
|
174
|
-
its job.
|
|
190
|
+
its job. `markErrorAsDisplayedBy` and `errorIsDisplayed` are exported for that:
|
|
191
|
+
|
|
192
|
+
```jsx
|
|
193
|
+
const PageErrorBoundary = ({ children, fallback }) => {
|
|
194
|
+
const [error, resetError] = useErrorBoundary();
|
|
195
|
+
if (!error) {
|
|
196
|
+
return children;
|
|
197
|
+
}
|
|
198
|
+
if (!isDisplayableError(error)) {
|
|
199
|
+
throw error; // our bug: unmarked, so it stays as loud as it is
|
|
200
|
+
}
|
|
201
|
+
markErrorAsDisplayedBy(error, "<PageErrorBoundary>");
|
|
202
|
+
return h(fallback, { error, resetError });
|
|
203
|
+
};
|
|
204
|
+
```
|