Closed minht11 closed 2 months ago
If pendingLoad
is null, you might be using loaders in an unexpected way. For example, using a loader in a component while it's not exported by the page rendering that component.
A reproduction will really help here. Focus on the page where this happened and its components. The templates should be irrelevant.
@minht11 I can't help if you don't share the code relevant to using data loaders. This would be helpful to provide runtime warnings in the future to help users detect problems
I know, I haven't been able to reproduce it myself yet, but I patched the package to show more information when error occurs. This one does not have data
This one has data
// Send entry to allow debugging
+ if (!entry.pendingLoad) {
+ throw new TypeError("Unknown error. Cannot read properties of null (reading 'then')", {
+ cause: stringifyCircularJSON({
+ staged: !!entry.staged,
+ error: !!entry.error.value,
+ isLoading: entry.isLoading.value,
+ ext: {
+ asyncStatus: entry.ext?.asyncStatus.value,
+ status: entry.ext?.status.value,
+ },
+ routePath: entry.route?.path,
+ routeName: entry.route?.name,
+ toPath: entry.to?.fullPath,
+ toName: entry.to?.name,
+ data: entry.data.value ? 'has data' : 'no data',
+ isPendingLoad: entry.pendingLoad ? 'is pending' : 'no pending',
+ isPendingTo: entry.pendingTo ? 'is pending' : 'no pending',
+ })
+ });
+ }
Is there anything I could log that could be helpfull?
Yes, the code of the page for that route and the code of the components using any of the loaders that is rendered by that page
I can't share the code, loaders are used in multiple components and levels, not one clean snippet, issue also occurs in multiple pages. Anyway I will still try to narrow it down, I thought logging some information when error occurs, like if for some reason loader wasn't staged (just a random example, could help.
Anyway I will still try to narrow it down
Yes, please.
Took a lot of time, but I managed to reproduce it.
Issue occurs when one of the loaders throws an error and you try to navigate to same page again.
// App.vue
<script lang="ts" setup>
import { ref } from 'vue';
import { RouterView, useRouter } from 'vue-router';
const router = useRouter();
const isError = ref(false);
router.onError(() => {
isError.value = true;
});
const reset = () => {
isError.value = false;
router.push('/');
};
</script>
<template>
<div v-if="isError">
Error happened
<button @click="reset">Login</button>
</div>
<div v-else>
<RouterView />
</div>
</template>
// pages/index.vue
<script lang="ts">
import { defineBasicLoader } from 'unplugin-vue-router/data-loaders/basic';
import { useRouter } from 'vue-router';
export const useHomePageData = defineBasicLoader(() => Promise.resolve(true));
</script>
<script lang="ts" setup>
useHomePageData();
const router = useRouter();
const details = () => router.push({ name: '/details' });
</script>
<template>
<button @click="details">Go to details</button>
</template>
// pages/details.vue
<script lang="ts">
import { defineBasicLoader } from 'unplugin-vue-router/data-loaders/basic';
export const useDetailsPageData = defineBasicLoader(async () => {
throw new Error('Not implemented');
});
</script>
<script lang="ts" setup>
// Empty
</script>
<template>Details Page</template>
https://github.com/user-attachments/assets/d66dcef2-4cfe-4610-945a-fd1a4cc84706
Thanks! the online repro is great, no need to paste the code here too when you do that 😄 It seems like the conditional display of the RouterView is related to the bug, if you remove it, it works. Maybe that helps you out in the meantime.
In your case, the issue came down to having the duplicated navigation of /
, if you avoid it, you also avoid the problem.
Yeah duplicated navigation is the cause, we saw in few more cases, not only with errors, but also when clicking the link of the active page on sidebar and later navigating somewhere else would produce an error, though it had some before enter guards and nested layouts.
Workaround for that one was just hiding the link, other cases like the one in the repo are trickier, because what should you do after error happens if you can't navigate.
After upgrade to latest version of unplugin-router-router and using pinia colada, I noticed errors in sentry.
I do not have a reproduction but I narrowed it down to this: https://github.com/posva/unplugin-vue-router/blob/fb772a28baf1c1daa6c801a246554cee9e29997e/src/data-loaders/defineLoader.ts#L345-L350
Promise is asserted as not being null, but at least from the Sentry errors that is not the case. Maybe it is race condition thing, most of the issues are from android, though I see some macs as well. I haven't seen it myself.