Error handling inside server routes located inside /server/routes

I'm trying to have it so when my server route fails it redirects to the full screen error page. I'm trying to do this by using the createError function inside the event handler. This isn't redirecting me to the fullscreen error page but instead it goes to the failing route on the client. So for example if my server route: /login/microsoft/callback fails it shows met the /login/microsoft/callback path inside the browser and will throw the vue router warning "No match found for location with path "/login/microsoft/callback". I feel like i'm missing something but i can't get my head around it. Any help or suggestions would be greatly appreciated.
8 Replies
kapa.ai
kapa.ai2d ago
Hi @Stig Vanbrabant. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- To handle errors in server routes located inside the /server/routes directory and redirect to a full-screen error page, you need to use the createError function correctly. However, there are a few things to consider: 1. In server routes, createError doesn't automatically trigger a full-screen error page. Instead, it's used to create an error response that can be handled on the client side. 2. To show a full-screen error page, you need to handle the error on the client side and use showError or throw a fatal error. Here's a suggested approach: 1. In your server route, use createError to generate an error response:
// server/routes/login/microsoft/callback.ts
export default defineEventHandler((event) => {
// Your authentication logic here
// If there's an error:
throw createError({
statusCode: 401,
statusMessage: 'Authentication failed',
data: { reason: 'Invalid token' } // Optional: Add any data you want to pass to the client
})
})
// server/routes/login/microsoft/callback.ts
export default defineEventHandler((event) => {
// Your authentication logic here
// If there's an error:
throw createError({
statusCode: 401,
statusMessage: 'Authentication failed',
data: { reason: 'Invalid token' } // Optional: Add any data you want to pass to the client
})
})
2. On the client side, handle this error in your page component or in a plugin. You can use useFetch or $fetch to call your API and handle the error:
<script setup>
const { data, error } = await useFetch('/api/login/microsoft/callback')

if (error.value) {
throw createError({
...error.value,
fatal: true
})
}
</script>
<script setup>
const { data, error } = await useFetch('/api/login/microsoft/callback')

if (error.value) {
throw createError({
...error.value,
fatal: true
})
}
</script>
By setting fatal: true, you ensure that the error will trigger the full-screen error page as mentioned in the Nuxt documentation (https://nuxt.com/docs/getting-started/error-handling#createerror). 3. Make sure you have an error.vue file in your project root to customize the error page:
<template>
<div>
<h1>{{ error.statusCode }}</h1>
<p>{{ error.message }}</p>
</div>
</template>

<script setup>
const props = defineProps({
error: Object
})
</script>
<template>
<div>
<h1>{{ error.statusCode }}</h1>
<p>{{ error.message }}</p>
</div>
</template>

<script setup>
const props = defineProps({
error: Object
})
</script>
This approach should redirect to the full-screen error page when your server route fails. Remember that server-side errors are not automatically propagated to the client-side as full-screen errors. You need to handle them explicitly on the client side to achieve the behavior you're looking for. Nuxt Error Handling documentation (https://nuxt.com/docs/getting-started/error-handling) provides more detailed information on error handling in different parts of your Nuxt application. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2d ago
<@1185156724261408809> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Stig Vanbrabant
Stig VanbrabantOP2d ago
@kapa.ai The thing is that i am not manually calling that route from within the client, it is an oauth callback route.. So handling it like this isn't really an option. @kapa.ai do you know how the handle it best in that case?
kapa.ai
kapa.ai2d ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- Based on the previous conversation and your follow-up question, I understand you're looking for the best way to handle errors in server routes and trigger a full-screen error page. Here's the recommended approach: 1. In your server route, use createError as mentioned before:
// server/routes/login/microsoft/callback.ts
export default defineEventHandler((event) => {
// Your authentication logic here
// If there's an error:
throw createError({
statusCode: 401,
statusMessage: 'Authentication failed',
fatal: true // Add this to ensure it's treated as a fatal error
})
})
// server/routes/login/microsoft/callback.ts
export default defineEventHandler((event) => {
// Your authentication logic here
// If there's an error:
throw createError({
statusCode: 401,
statusMessage: 'Authentication failed',
fatal: true // Add this to ensure it's treated as a fatal error
})
})
2. In your client-side code (e.g., a page component or plugin), use useFetch or $fetch to call your API and handle the error:
<script setup>
try {
const { data } = await useFetch('/api/login/microsoft/callback')
// Handle successful response
} catch (error) {
showError(error)
}
</script>
<script setup>
try {
const { data } = await useFetch('/api/login/microsoft/callback')
// Handle successful response
} catch (error) {
showError(error)
}
</script>
The key here is to use the showError function, which is specifically designed to display the full-screen error page in Nuxt 3 as documented in the Nuxt API (https://nuxt.com/docs/api/utils/show-error). This function will trigger the error page and set the error in the state using useError(). 3. Make sure you have an error.vue file in your project root to customize the error page:
<template>
<div>
<h1>{{ error.statusCode }}</h1>
<p>{{ error.statusMessage }}</p>
<button @click="handleError">Go back</button>
</div>
</template>

<script setup>
const props = defineProps({
error: Object
})

const handleError = () => clearError({ redirect: '/' })
</script>
<template>
<div>
<h1>{{ error.statusCode }}</h1>
<p>{{ error.statusMessage }}</p>
<button @click="handleError">Go back</button>
</div>
</template>

<script setup>
const props = defineProps({
error: Object
})

const handleError = () => clearError({ redirect: '/' })
</script>
This approach should effectively handle errors from your server routes and display them as full-screen error pages. The showError function ensures that the error is properly propagated and displayed, while the error.vue file allows you to customize how the error is presented to the user. Remember, as mentioned in the Nuxt documentation (https://nuxt.com/docs/getting-started/error-handling#error-page), the error page is a separate page load, so any registered middleware will run again. You can use useError in middleware to check if an error is being handled if needed. Nuxt Error Handling documentation (https://nuxt.com/docs/getting-started/error-handling) provides more detailed information on error handling in different parts of your Nuxt application. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2d ago
<@1185156724261408809> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Stig Vanbrabant
Stig VanbrabantOP2d ago
@kapa.ai i think you have missed some context so let me try again. The thing is that i am not manually calling that route from within the client, as it is an oauth callback route.. So handling it like this isn't really an option in my case. Do you know how to best handle this knowing the route is an oauth callback route?
kapa.ai
kapa.ai2d ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- I apologize for the misunderstanding. You're right, I missed that crucial context about the route being an OAuth callback. Let's address this scenario specifically for an OAuth callback route. For OAuth callback routes, which are typically accessed directly by the OAuth provider's redirect, handling errors is indeed different. Here's a better approach for this situation: 1. In your OAuth callback route, you can use sendRedirect to redirect to a client-side error page when an error occurs:
// server/routes/login/microsoft/callback.ts
export default defineEventHandler(async (event) => {
try {
// Your OAuth callback logic here
// If successful, redirect to a success page or home page
return sendRedirect(event, '/dashboard')
} catch (error) {
// If there's an error, redirect to a client-side error page
return sendRedirect(event, '/auth-error?message=' + encodeURIComponent(error.message))
}
})
// server/routes/login/microsoft/callback.ts
export default defineEventHandler(async (event) => {
try {
// Your OAuth callback logic here
// If successful, redirect to a success page or home page
return sendRedirect(event, '/dashboard')
} catch (error) {
// If there's an error, redirect to a client-side error page
return sendRedirect(event, '/auth-error?message=' + encodeURIComponent(error.message))
}
})
2. Create a client-side route to handle the error, for example, /pages/auth-error.vue:
<script setup>
const route = useRoute()
const error = ref(null)

onMounted(() => {
error.value = route.query.message
if (error.value) {
showError({
statusCode: 401,
statusMessage: 'Authentication Error',
message: error.value
})
}
})
</script>

<template>
<div>Handling authentication error...</div>
</template>
<script setup>
const route = useRoute()
const error = ref(null)

onMounted(() => {
error.value = route.query.message
if (error.value) {
showError({
statusCode: 401,
statusMessage: 'Authentication Error',
message: error.value
})
}
})
</script>

<template>
<div>Handling authentication error...</div>
</template>
This approach allows you to: 1. Handle the error server-side in the OAuth callback route. 2. Redirect to a client-side route that can then trigger the full-screen error page. The sendRedirect function is part of the h3 library used by Nitro, Nuxt's server engine, as mentioned in the Nitro documentation (https://nitro.unjs.io/guide/routing#error-handling). By using this method, you're able to handle errors in your OAuth callback route and still leverage Nuxt's error handling capabilities to show a full-screen error page. Remember to have your error.vue file set up in your project root to customize the full-screen error page, as described in the Nuxt documentation (https://nuxt.com/docs/getting-started/error-handling#error-page). This approach should work well for OAuth callback routes where you don't have direct control over the initial request but need to handle errors and display them appropriately in your Nuxt application. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2d ago
<@1185156724261408809> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Want results from more Discord servers?
Add your server