Reputation: 2344
I have an Angular Universal application running, which works fine, except for the fact that if an error occurs in the Angular code while rendering, instead of just spitting out a 500 response, it'll keep loading forever, until the server decides it's enough and spits out a 503.
An example of a failing page is https://msp-navigator.com/company/BpQzpAHaSFWbXvsgt3gc/saaslio. This one fails because it's only accessible to Admins, but in the resolve, due to a mistake, if you're not logged in, the user is undefined and the check fails. (user.roles?.includes('Admin')
=> user?.roles?.includes('Admin')
. An example of a page that doesn't fail is https://msp-navigator.com/company/FsAqspiNe7jPCyOsIhT7/saaslio
The route in server.ts
is defined like this:
server.get('*', async (req, res, next) => {
const origin = 'https://' + req.header('host');
let settings: any;
try {
settings = await axios.get(environment.config.apiUrl + '/settings', {headers: {origin}});
} catch (e) {
res.sendStatus(404);
return;
}
const transaction = Sentry.startTransaction({ op: 'main', name: 'Main' });
Sentry.configureScope(scope => scope.setSpan(transaction));
try {
console.log('test 1');
res.render(indexHtml, {
req,
providers: [
{ provide: APP_BASE_HREF, useValue: req.baseUrl },
{ provide: SETTINGS, useValue: settings.data }
],
});
} catch (e) {
console.log('test 2');
res.send(500);
}
transaction.finish();
});
In case of an error "test 1" is logged, then the error, but "test 2" is never logged.
I'm not sure what other code I can share, but please ask.
Any ideas on how I can resolve this?
Upvotes: 0
Views: 669
Reputation: 34435
This is because render is asynchronous, which means that errors will not be handled by your try/catch
. But you can provide a callback to render
res.render(indexHtml, {
req,
providers: [
{ provide: APP_BASE_HREF, useValue: req.baseUrl },
{ provide: SETTINGS, useValue: settings.data }
],
}, (err: Error, html: string) =>
{
if(!html)
{
res.status(500);
}
res.send(html || err.message);
});
Upvotes: 2