54 lines
1.7 KiB
JavaScript
54 lines
1.7 KiB
JavaScript
import { AsyncLocalStorage } from "node:async_hooks";
|
|
import { NodeApp } from "astro/app/node";
|
|
function createAppHandler(app, options) {
|
|
const als = new AsyncLocalStorage();
|
|
const logger = app.getAdapterLogger();
|
|
process.on("unhandledRejection", (reason) => {
|
|
const requestUrl = als.getStore();
|
|
logger.error(`Unhandled rejection while rendering ${requestUrl}`);
|
|
console.error(reason);
|
|
});
|
|
const originUrl = options.experimentalErrorPageHost ? new URL(options.experimentalErrorPageHost) : void 0;
|
|
const prerenderedErrorPageFetch = originUrl ? (url) => {
|
|
const errorPageUrl = new URL(url);
|
|
errorPageUrl.protocol = originUrl.protocol;
|
|
errorPageUrl.host = originUrl.host;
|
|
return fetch(errorPageUrl);
|
|
} : void 0;
|
|
return async (req, res, next, locals) => {
|
|
let request;
|
|
try {
|
|
request = NodeApp.createRequest(req, {
|
|
allowedDomains: app.getAllowedDomains?.() ?? []
|
|
});
|
|
} catch (err) {
|
|
logger.error(`Could not render ${req.url}`);
|
|
console.error(err);
|
|
res.statusCode = 500;
|
|
res.end("Internal Server Error");
|
|
return;
|
|
}
|
|
const routeData = app.match(request, true);
|
|
if (routeData) {
|
|
const response = await als.run(
|
|
request.url,
|
|
() => app.render(request, {
|
|
addCookieHeader: true,
|
|
locals,
|
|
routeData,
|
|
prerenderedErrorPageFetch
|
|
})
|
|
);
|
|
await NodeApp.writeResponse(response, res);
|
|
} else if (next) {
|
|
return next();
|
|
} else {
|
|
const response = await app.render(req, { addCookieHeader: true, prerenderedErrorPageFetch });
|
|
await NodeApp.writeResponse(response, res);
|
|
}
|
|
};
|
|
}
|
|
export {
|
|
createAppHandler
|
|
};
|