Tengo una aplicación de reacción isomorfa y me gustaría pasar de alguna manera el estado entre el middleware express.
Tengo la siguiente ruta expresa que maneja el envío de formularios:
export const createPaymentHandler = async (req: Request, res: Response, next: NextFunction) => { const { field } = req.body; if (!paymentType) { res.locals.syncErrors = { field: 'some error.' }; next(); return; } try { const { redirectUrl } = await makeRequest<CreatePaymentRequest, CreatePaymentResponse>({ body: { paymentType }, method: HttpMethod.POST }); res.redirect(redirectUrl); } catch (err) { error(err); res.locals.serverError = true; next(); } };El siguiente middleware está manejando el renderizado.
En este momento estoy usando res.locals , ¿hay una mejor manera o un patrón reconocido?
Debido a que su controlador es asíncrono, debe pasar el err a next , así:
next(err);Para que su middleware procese el error, en lugar de que lo detecte el controlador de errores predeterminado, debe tener cuatro parámetros:
app.use((err, req, res, next) => { // handle the error })También vale la pena señalar que los controladores de errores deben especificarse después de otro middleware. Para su caso, podría tener sentido usar un middleware de "éxito" normal junto con un controlador de errores, en lugar de combinar los dos en un middleware.
Finalmente, tenga en cuenta que pasar err como parámetro es específico de los controladores de errores. Si solo desea pasar algunos datos a su próximo middleware, lo haría modificando el req :
req.x = 'some data' next() Luego, el parámetro req del siguiente middleware tendrá los datos que configuró.
Lectura adicional: https://expressjs.com/en/guide/using-middleware.html#middleware.error-handling
En mi opinión, su pregunta se trata más de pasar algunos datos al siguiente middleware. Dado que la lógica de representación es manejada por el siguiente middleware, la ruta rápida no debería preocuparse por cómo se usan los datos. Su enfoque se ve bien.
res.locals es la forma recomendada de pasar datos al siguiente middleware. De los documentos:
Esta propiedad es útil para exponer información a nivel de solicitud, como el nombre de la ruta de la solicitud, el usuario autenticado, la configuración del usuario, etc.
Además, dado que las variables añadidas estarán en el ámbito de la solicitud actual, los datos solo estarán disponibles para el ciclo de vida de la solicitud actual. Quizás pueda establecer una convención para agregar una clave de state en res.locals para almacenar todas sus variables de estado, pero el enfoque actual también funcionaría bien.
Si está pasando información liviana al siguiente middleware con fines de representación, entonces está bien aplicar res.locals . Sin embargo, es posible que desee buscar error-handling para errores generales, como errores internos.
Considere el siguiente manejo de errores
function notFoundHandler(req, res, next) { res.status(404).render('notFoundPage', { error: '404 - not found' }); } function badRequestHandler(err, req, res, next) { res.status(400).render('badRequestPage', { error: 'Bad request' }); } function errorHandler(err, req, res, next) { res.status(err.status || 500).render('errorPage', { error: 'Internal server error' }); } app.use(notFoundHandler); app.use(badRequestHandler); app.use(errorHandler);Ahora, en lugar de pasar los detalles del error al siguiente middleware, simplemente dejaría que fluya a los controladores de errores, por ejemplo
export const createPaymentHandler = async (req: Request, res: Response, next: NextFunction) => { const { field } = req.body; if (!paymentType) { res.status(400); return next(); // This will hit the Bad Request handler } try { const { redirectUrl } = await makeRequest < CreatePaymentRequest, CreatePaymentResponse > ({ body: { paymentType }, method: HttpMethod.POST }); res.redirect(redirectUrl); } catch (err) { res.status(500); return next(err); // This will hit the Error Handler } };