gpt4 book ai didi

javascript - 无法在 React 服务器端渲染中处理 UnhandledPromiseRejectionWarning

转载 作者:行者123 更新时间:2023-11-30 21:18:37 25 4
gpt4 key购买 nike

我有一个在客户端和服务器上呈现的 React 应用程序。当任何组件的 render() 失败时(由于我的代码中的错误,例如试图读取 undefined object 的属性),然后如果我从浏览器中的另一个页面导航,那么我会在浏览器开发者控制台。

但是,当我触发相同代码的服务器端呈现(通过直接将浏览器指向包含故障组件的有问题的路由)时,我只会在服务器的控制台中收到如下错误:

(node:97192) UnhandledPromiseRejectionWarning:未处理的 promise 拒绝(拒绝 ID:1):TypeError:无法读取未定义的属性“tagDefinitionId”

没有堆栈跟踪,调试起来有点困难。

问题:有没有办法在服务器端渲染期间一揽子捕获所有 render() 失败?

触发服务器端渲染以响应被请求的 Node-Express 端点的代码如下。我相信未处理的 promise 拒绝发生在 renderToString() 内部,但此函数返回一个字符串,而不是 promise。

`

import configureStore from '../../redux/store';
import { renderToString } from 'react-dom/server';
import { Provider } from 'react-redux';
import React from 'react';
import RouterContext from 'react-router/lib/RouterContext';
import createMemoryHistory from 'react-router/lib/createMemoryHistory';
import match from 'react-router/lib/match';
import template from './template';
import routes from '../../routes';

const clientAssets = require(KYT.ASSETS_MANIFEST);

app.use((request, response) => {
const history = createMemoryHistory(request.originalUrl);

match({ routes, history }, (error, redirectLocation, renderProps) => {
if (error) {
response.status(500).send(error.message);
} else if (redirectLocation) {
response.redirect(302, `${redirectLocation.pathname}${redirectLocation.search}`);
} else if (renderProps) {
// This is the initial store
const store = configureStore();

// When a React Router route is matched then we render
// the components and assets into the template.
const render = () => {
// Grab the initial state from our Redux store
const initialState = JSON.stringify(store.getState());

let isNotFoundRoute = false;
if (renderProps.routes[1].path === '*') {
isNotFoundRoute = true;
}

// Populate the HTML document with the current redux store
response.status(isNotFoundRoute ? 404 : 200).send(template({
root: renderToString(
<Provider store={store}>
<RouterContext {...renderProps} />
</Provider>
),
cssBundle: clientAssets.main.css,
jsBundle: clientAssets.main.js,
initialState,
}));
};

// Fetch the components from the renderProps and when they have
// promises, add them to a list of promises to resolve before starting
// a HTML response
fetchComponentData(store.dispatch, renderProps.components, renderProps.params).then(render);
} else {
response.status(404).send('Not found');
}
});
});

`

我认为唯一可能与此处相关的自定义代码导入是 template.js:

`

import Helmet from 'react-helmet';

export default (vo) => {
const helmet = Helmet.rewind();
return `
<!DOCTYPE html>
<html lang="en" ${helmet.htmlAttributes.toString()} >
<head>
${helmet.title.toString()}
<meta httpEquiv="X-UA-Compatible" content="IE=edge" />
<meta charSet='utf-8' />
<meta httpEquiv="Content-Language" content="en" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="white" />
${helmet.meta.toString()}
${helmet.link.toString()}
<link id="favicon" rel="shortcut icon" href="/favicon.png" sizes="16x16 32x32" type="image/png" />
<link rel="manifest" href="manifest.json">
${vo.cssBundle ? '<link rel="stylesheet" type="text/css" href="' + vo.cssBundle + '">' : ''}
</head>
<body ${helmet.bodyAttributes.toString()} >
<div id="root" class="root"><div>${vo.root}</div></div>
<script>
window.__PRELOADED_STATE__ = ${vo.initialState}
</script>
<script async src="${vo.jsBundle}"></script>
</body>
</html>
`;
};

`

最佳答案

是的,有a catch-all您可以使用它来记录未处理的拒绝的堆栈跟踪,但您最好简单地处理它们。事实上,当您的 render 函数中的某些内容抛出异常时,没有任何东西会捕捉到它。

我建议将您的脚本重组为

app.use((request, response) => {
const history = createMemoryHistory(request.originalUrl);

new Promise((resolve, reject) => {
match({ routes, history }, (error, redirectLocation, renderProps) => {
if (error) reject(error);
else resolve({redirectLocation, renderProps});
}).then(({redirectLocation, renderProps}) => {
if (redirectLocation) {
return {status: 302, target: redirectLocation.pathname + redirectLocation.search};
} else if (!renderProps) {
return {status: 404, content: 'Not found'};
} else {
const store = configureStore();
return fetchComponentData(store.dispatch, renderProps.components, renderProps.params).then(() => {
const initialState = JSON.stringify(store.getState());
const isNotFoundRoute = (renderProps.routes[1].path === '*');
const content = template({
root: renderToString(
<Provider store={store}>
<RouterContext {...renderProps} />
</Provider>
),
cssBundle: clientAssets.main.css,
jsBundle: clientAssets.main.js,
initialState,
});
return {status: isNotFoundRoute ? 404 : 200, content};
});
}
}).catch(err => { // THIS IS IMPORTANT!
console.error(err); // or err.message and err.stack and everything, maybe including route
return {status: 500, content: 'Sorry, we\'ll look into it'}; // or err.message if you trust it
}).then(({status, target, content}) => {
if (status >= 300 && status < 400)
response.redirect(status, target);
else
respose.status(status).send(content);
if (status >= 400)
console.debug(…)
});
});

关于javascript - 无法在 React 服务器端渲染中处理 UnhandledPromiseRejectionWarning,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45414673/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com