You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
-**data-loaders:** allow nested loaders to run on invalidation ([0665635](https://github.com/posva/unplugin-vue-router/commit/0665635f78a3cbebcb676c288545e870f76a9243)), closes [#583](https://github.com/posva/unplugin-vue-router/issues/583)
- mkdir if parent dir does not exists ([#516](https://github.com/posva/unplugin-vue-router/issues/516)) ([6bea24a](https://github.com/posva/unplugin-vue-router/commit/6bea24a284871b0948a33e41c63aa11ce0caed19))
-**loaders:** ensure loads when a navigation is missed ([b799598](https://github.com/posva/unplugin-vue-router/commit/b799598bde55e77cd7266f97efbe3c9e450f9b2d)), closes [#495](https://github.com/posva/unplugin-vue-router/issues/495)
44
+
-**loaders:** make data possibly undefined in some cases([#506](https://github.com/posva/unplugin-vue-router/issues/506)) ([10112a0](https://github.com/posva/unplugin-vue-router/commit/10112a0309e27b8caffb1990740081d286fd84a7))
45
+
- upgrade support for pinia colada 0.13.0 ([b01dce4](https://github.com/posva/unplugin-vue-router/commit/b01dce4f4cdb47e22efe9c00ea902a9f1d3316a5))
46
+
47
+
### Features
48
+
49
+
-**data-loaders:** adapt colada to support always defined data ([a1cda5d](https://github.com/posva/unplugin-vue-router/commit/a1cda5de246cc2931bb3a311c52cdc340e1bcf33))
50
+
-**data-loaders:** allow `data` to always be defined ([7cf7796](https://github.com/posva/unplugin-vue-router/commit/7cf7796ca82e2589b68882bfef708c755b65c77b)), closes [#319](https://github.com/posva/unplugin-vue-router/issues/319)
51
+
-**data-loaders:** allow default type for errors ([5ec4076](https://github.com/posva/unplugin-vue-router/commit/5ec4076add65bbfa62a57c2c1cb8e230c6ba3e1b))
- support vite 6 ([b1c4f6c](https://github.com/posva/unplugin-vue-router/commit/b1c4f6c16cb14cd60bce677e77b1d0cd8ef6afc9))
54
+
55
+
### BREAKING CHANGES
56
+
57
+
-**data-loaders:** The default type for `error` is now `Error`.
58
+
-**data-loaders:** Based on the `options` passed to a `defineLoader()` function, the `data` will now be possibly `undefined`. This enables a more convenient typing
59
+
-**data-loaders:**: The `DataLoaderPlugin` must be imported from `unplugin-vue-router/data-loaders` instead of `unplugin-vue-router/runtime`.
@@ -169,8 +229,8 @@ internally to represent the folder structure.
169
229
170
230
This patch contains the necessary fixes to allow importing the data loaders. However, they cannot be imported from `vue-router/auto` nor from `unplugin-vue-router/runtime`. Instead, they should be imported from `unplugin-vue-router/data-loaders/...`. This is needed as some of the loaders depends on extra packages that not all users have installed. At the moment, there are two data loaders
Based on the feedback of the RFC, the Data Loaders have been redesigned from the ground up and are now way more flexible and powerful. As a result, if you were using the experimental data loaders, make sure to check the list of breaking changes and the new RFC at https://uvr.esm.is/rfcs/data-loaders. We are looking for early testers and feedback!
263
+
Based on the feedback of the RFC, the Data Loaders have been redesigned from the ground up and are now way more flexible and powerful. As a result, if you were using the experimental data loaders, make sure to check the list of breaking changes and the new RFC at <https://uvr.esm.is/rfcs/data-loaders>. We are looking for early testers and feedback!
204
264
205
265
For people using the file-based routing, you now need to add `unplugin-vue-router/client` to the `types` property of your tsconfig. See [setup](https://uvr.esm.is/introduction.html#setup) for an example.
206
266
@@ -260,7 +320,7 @@ For people using the file-based routing, you now need to add `unplugin-vue-route
260
320
moved out of the basic loader to an extended one [pinia-colada](https://uvr.esm.is/data-loaders/colada/) and the [basic loader](https://uvr.esm.is/data-loaders/basic/)
261
321
has no cache. All of the pending bugs have also been fixed.
262
322
I recommend you to give the RFC examples a new read to get
263
-
setup: https://uvr.esm.is/data-loaders/rfc. Most of the changes are
323
+
setup: <https://uvr.esm.is/data-loaders/rfc>. Most of the changes are
264
324
simplifying things by removing them.
265
325
Here is a list of the breaking changes to simplify
266
326
migration:
@@ -269,9 +329,9 @@ For people using the file-based routing, you now need to add `unplugin-vue-route
269
329
- Manual work needed to add loaders with `HasDataLoaderMeta` has been
270
330
removed. It is just no longer needed. Loaders are picked up from lazy
271
331
loaded components and must otherwise be directly added to a `meta.loaders`
272
-
array. See the example at https://uvr.esm.is/data-loaders/rfc.html#basic-example
332
+
array. See the example at <https://uvr.esm.is/data-loaders/rfc.html#basic-example>
273
333
- The function `setupDataFetchingGuard` has been replaced with a Vue
274
-
Plugin. See https://uvr.esm.is/data-loaders/rfc.html#data-loader-setup
334
+
Plugin. See <https://uvr.esm.is/data-loaders/rfc.html#data-loader-setup>
275
335
for details.
276
336
- If you were relying on `cacheTime`, use the `staleTime` option in the
277
337
new [`defineColadaLoader()`](https://uvr.esm.is/rfcs/data-loaders/colada) based off [@pinia/colada](https://github.com/posva/pinia-colada)
@@ -323,7 +383,7 @@ For people using the file-based routing, you now need to add `unplugin-vue-route
323
383
by adding a library that properly handles the caching. This new strategy
324
384
will also enable other integrations like VueFire, Apollo, and custom
325
385
ones. Keep an eye (subscribe) to the RFC for news and to discus about
326
-
the future of Data Loaders: https://github.com/vuejs/rfcs/discussions/460
386
+
the future of Data Loaders: <https://github.com/vuejs/rfcs/discussions/460>
327
387
- since data loaders aren't meant to be awaited in script
328
388
setup (they are awaited at the navigation level), they now return a
329
389
promise of the raw data only, not of the UseDataLoaderReturn, to make it
Copy file name to clipboardExpand all lines: docs/data-loaders/error-handling.md
+98-3Lines changed: 98 additions & 3 deletions
Original file line number
Diff line number
Diff line change
@@ -1,10 +1,12 @@
1
-
# Error Handling
1
+
# Error handling
2
2
3
3
By default, all errors thrown in a loader are considered _unexpected errors_: they will abort the navigation, just like in a navigation guard. Because they abort the navigation, they will not appear in the `error` property of the loader. Instead, they will be intercepted by Vue Router's error handling with `router.onError()`.
4
4
5
5
However, if the loader is **not navigation-aware**, the error cannot be intercepted by Vue Router and will be kept in the `error` property of the loader. This is the case for _lazy loaders_ and [_reloading data_](./reloading-data.md).
6
6
7
-
To be able to intercept errors in blocking loaders, we can specify a list of error classes that are considered _expected errors_. This allows blocking loader to **not abort the navigation** and instead keep the error in the `error` property of the loader and let the page locally display the error state.
7
+
## Defining expected Errors
8
+
9
+
To be able to intercept errors in non-lazy loaders, we can specify a list of error classes that are considered _expected errors_. This allows blocking loader to **not abort the navigation** and instead keep the error in the `error` property of the loader and let the page locally display the error state.
It also accepts a function that returns a boolean to determine if the error is expected or not.
65
+
Then you need to opt-in in the loader by setting the `errors` option to `true` to keep the error in the `error` property of the loader.
66
+
67
+
```ts{7} twoslash
68
+
import 'unplugin-vue-router/client'
69
+
import './typed-router.d'
70
+
import { defineBasicLoader } from 'unplugin-vue-router/data-loaders/basic'
71
+
// @moduleResolution: bundler
72
+
// ---cut---
73
+
export const useUserData = defineBasicLoader(
74
+
async (to) => {
75
+
throw new Error('Something went wrong')
76
+
// ...
77
+
// ---cut-start---
78
+
return { name: 'John' }
79
+
// ---cut-end---
80
+
},
81
+
{
82
+
errors: true,
83
+
}
84
+
)
85
+
```
86
+
87
+
::: details Why is `errors: true` needed?
88
+
89
+
One of the benefits of Data Loaders is that they ensure the `data` to be ready before the component is rendered. With expected errors, this is no longer true and `data` can be `undefined`:
90
+
91
+
```ts{11} twoslash
92
+
import 'unplugin-vue-router/client'
93
+
import './typed-router.d'
94
+
import { defineBasicLoader } from 'unplugin-vue-router/data-loaders/basic'
If you need more control over the error handling, you can provide a function to the `errors` option. This option is available in both the `DataLoaderPlugin` and when defining a loader.
61
118
62
119
```ts{3-9} twoslash
63
120
import 'unplugin-vue-router/client'
@@ -79,3 +136,41 @@ app.use(DataLoaderPlugin, {
79
136
},
80
137
})
81
138
```
139
+
140
+
## Handling both, local and global errors
141
+
142
+
TODO: this hasn't been implemented yet
143
+
144
+
## Error handling priority
145
+
146
+
When you use both, global and local error handling, the local error handling has a higher priority and will override the global error handling. This is how the local and global errors are checked:
147
+
148
+
- if local `errors` is `false`: abort the navigation -> `data` is not `undefined`
149
+
- if local `errors` is `true`: rely on the globally defined `errors` option -> `data` is possibly `undefined`
150
+
- else: rely on the local `errors` option -> `data` is possibly `undefined`
151
+
152
+
## TypeScript
153
+
154
+
You will notice that the type of `error` is `Error | null` even when you specify the `errors` option. This is because if we call the `reload()` method (meaning we are outside of a navigation), the error isn't discarded, it appears in the `error` property **without being filtered** by the `errors` option.
155
+
156
+
In practice, depending on how you handle the error, you will add a [type guard](https://www.typescriptlang.org/docs/handbook/advanced-types.html#user-defined-type-guards) inside the component responsible for displaying an error or directly in a `v-if` in the template.
If you want to be even stricter, you can override the default `Error` type with `unknown` (or anything else) by augmenting the `TypesConfig` interface.
0 commit comments