From 360f40ee7709caa4193ca72d70ad8a4bb06fadb8 Mon Sep 17 00:00:00 2001 From: Emanuele Stoppa Date: Mon, 18 Dec 2023 14:04:05 +0000 Subject: [PATCH 1/4] fix: handle middleware loading error --- .changeset/selfish-rings-occur.md | 5 +++++ packages/astro/src/core/middleware/loadMiddleware.ts | 10 ++++++++-- packages/astro/src/vite-plugin-astro-server/route.ts | 2 +- 3 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 .changeset/selfish-rings-occur.md diff --git a/.changeset/selfish-rings-occur.md b/.changeset/selfish-rings-occur.md new file mode 100644 index 000000000000..e5722bb95f23 --- /dev/null +++ b/.changeset/selfish-rings-occur.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Correctly handle the error in case the middleware throws a runtime error diff --git a/packages/astro/src/core/middleware/loadMiddleware.ts b/packages/astro/src/core/middleware/loadMiddleware.ts index 4f524ee52756..d67e4f33ca39 100644 --- a/packages/astro/src/core/middleware/loadMiddleware.ts +++ b/packages/astro/src/core/middleware/loadMiddleware.ts @@ -1,16 +1,22 @@ import type { ModuleLoader } from '../module-loader/index.js'; import { MIDDLEWARE_MODULE_ID } from './vite-plugin.js'; +import type { Logger } from '../logger/core.js'; /** * It accepts a module loader and the astro settings, and it attempts to load the middlewares defined in the configuration. * * If not middlewares were not set, the function returns an empty array. */ -export async function loadMiddleware(moduleLoader: ModuleLoader) { +export async function loadMiddleware(moduleLoader: ModuleLoader, logger: Logger) { try { const module = await moduleLoader.import(MIDDLEWARE_MODULE_ID); return module; - } catch { + } catch (e: any) { + logger.error( + 'middleware', + "Astro couldn't load the middleware because the module contains an error." + ); + logger.error('middleware', e.stack || e.message); return void 0; } } diff --git a/packages/astro/src/vite-plugin-astro-server/route.ts b/packages/astro/src/vite-plugin-astro-server/route.ts index 3196b951a796..b9d6c0ad549b 100644 --- a/packages/astro/src/vite-plugin-astro-server/route.ts +++ b/packages/astro/src/vite-plugin-astro-server/route.ts @@ -187,7 +187,7 @@ export async function handleRoute({ let mod: ComponentInstance | undefined = undefined; let options: SSROptions | undefined = undefined; let route: RouteData; - const middleware = await loadMiddleware(moduleLoader); + const middleware = await loadMiddleware(moduleLoader, logger); if (!matchedRoute) { if (config.i18n) { From 8251d5d60de7618ffeaa8de20f5ba5395876e53c Mon Sep 17 00:00:00 2001 From: Emanuele Stoppa Date: Mon, 18 Dec 2023 17:20:15 +0000 Subject: [PATCH 2/4] remove the try/catch --- .../astro/src/core/middleware/loadMiddleware.ts | 15 ++------------- .../astro/src/vite-plugin-astro-server/route.ts | 2 +- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/packages/astro/src/core/middleware/loadMiddleware.ts b/packages/astro/src/core/middleware/loadMiddleware.ts index d67e4f33ca39..7efcff440922 100644 --- a/packages/astro/src/core/middleware/loadMiddleware.ts +++ b/packages/astro/src/core/middleware/loadMiddleware.ts @@ -1,22 +1,11 @@ import type { ModuleLoader } from '../module-loader/index.js'; import { MIDDLEWARE_MODULE_ID } from './vite-plugin.js'; -import type { Logger } from '../logger/core.js'; /** * It accepts a module loader and the astro settings, and it attempts to load the middlewares defined in the configuration. * * If not middlewares were not set, the function returns an empty array. */ -export async function loadMiddleware(moduleLoader: ModuleLoader, logger: Logger) { - try { - const module = await moduleLoader.import(MIDDLEWARE_MODULE_ID); - return module; - } catch (e: any) { - logger.error( - 'middleware', - "Astro couldn't load the middleware because the module contains an error." - ); - logger.error('middleware', e.stack || e.message); - return void 0; - } +export async function loadMiddleware(moduleLoader: ModuleLoader) { + return await moduleLoader.import(MIDDLEWARE_MODULE_ID); } diff --git a/packages/astro/src/vite-plugin-astro-server/route.ts b/packages/astro/src/vite-plugin-astro-server/route.ts index b9d6c0ad549b..3196b951a796 100644 --- a/packages/astro/src/vite-plugin-astro-server/route.ts +++ b/packages/astro/src/vite-plugin-astro-server/route.ts @@ -187,7 +187,7 @@ export async function handleRoute({ let mod: ComponentInstance | undefined = undefined; let options: SSROptions | undefined = undefined; let route: RouteData; - const middleware = await loadMiddleware(moduleLoader, logger); + const middleware = await loadMiddleware(moduleLoader); if (!matchedRoute) { if (config.i18n) { From 2cb5d5aaa4b16798223cddb7cec27ca1f3168ed3 Mon Sep 17 00:00:00 2001 From: Emanuele Stoppa Date: Mon, 18 Dec 2023 20:42:06 +0000 Subject: [PATCH 3/4] rethrow error --- packages/astro/src/core/errors/errors-data.ts | 20 +++++++++++++++++++ .../src/core/middleware/loadMiddleware.ts | 10 +++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/packages/astro/src/core/errors/errors-data.ts b/packages/astro/src/core/errors/errors-data.ts index 047bb533721c..691162d595af 100644 --- a/packages/astro/src/core/errors/errors-data.ts +++ b/packages/astro/src/core/errors/errors-data.ts @@ -780,6 +780,26 @@ export const LocalsNotAnObject = { hint: 'If you tried to remove some information from the `locals` object, try to use `delete` or set the property to `undefined`.', } satisfies ErrorData; +/** + * @docs + * @description + * Thrown in development mode when middleware throws an error while attempting to loading it. + * + * For example: + * ```ts + * import {defineMiddleware} from "astro:middleware"; + * throw new Error("Error thrown while loading the middleware.") + * export const onRequest = defineMiddleware(() => { + * return "string" + * }); + * ``` + */ +export const MiddlewareCantBeLoaded = { + name: 'MiddlewareCantBeLoaded', + title: "Can't load the middleware.", + message: 'The middleware thrown an error while Astro was trying to loading it.', +} satisfies ErrorData; + /** * @docs * @see diff --git a/packages/astro/src/core/middleware/loadMiddleware.ts b/packages/astro/src/core/middleware/loadMiddleware.ts index 7efcff440922..2f1878827ab4 100644 --- a/packages/astro/src/core/middleware/loadMiddleware.ts +++ b/packages/astro/src/core/middleware/loadMiddleware.ts @@ -1,5 +1,7 @@ import type { ModuleLoader } from '../module-loader/index.js'; import { MIDDLEWARE_MODULE_ID } from './vite-plugin.js'; +import { MiddlewareCantBeLoaded } from '../errors/errors-data.js'; +import { AstroError } from '../errors/index.js'; /** * It accepts a module loader and the astro settings, and it attempts to load the middlewares defined in the configuration. @@ -7,5 +9,11 @@ import { MIDDLEWARE_MODULE_ID } from './vite-plugin.js'; * If not middlewares were not set, the function returns an empty array. */ export async function loadMiddleware(moduleLoader: ModuleLoader) { - return await moduleLoader.import(MIDDLEWARE_MODULE_ID); + try { + return await moduleLoader.import(MIDDLEWARE_MODULE_ID); + } catch (error: any) { + const astroError = new AstroError(MiddlewareCantBeLoaded); + astroError.cause = error.cause; + throw astroError; + } } From 47fe703ee2012344b2fd1113f06883c8022d56f5 Mon Sep 17 00:00:00 2001 From: Emanuele Stoppa Date: Tue, 19 Dec 2023 08:27:00 +0000 Subject: [PATCH 4/4] Update packages/astro/src/core/middleware/loadMiddleware.ts Co-authored-by: Arsh <69170106+lilnasy@users.noreply.github.com> --- packages/astro/src/core/middleware/loadMiddleware.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/astro/src/core/middleware/loadMiddleware.ts b/packages/astro/src/core/middleware/loadMiddleware.ts index 2f1878827ab4..135f7fbc479e 100644 --- a/packages/astro/src/core/middleware/loadMiddleware.ts +++ b/packages/astro/src/core/middleware/loadMiddleware.ts @@ -12,8 +12,7 @@ export async function loadMiddleware(moduleLoader: ModuleLoader) { try { return await moduleLoader.import(MIDDLEWARE_MODULE_ID); } catch (error: any) { - const astroError = new AstroError(MiddlewareCantBeLoaded); - astroError.cause = error.cause; + const astroError = new AstroError(MiddlewareCantBeLoaded, undefined, { cause: error }); throw astroError; } }