El error lanzado por un método de clase no es capturado por el manejador de solicitudes.
Creé una clase Transporter para enviar correos electrónicos:
export class MailTransporter {
receiver: string;
private transporter: Transporter;
constructor(receiver: string) {
this.receiver = receiver;
this.transporter = this.getTransporter();
}
private getTransporter() {
const { MAIL_USERNAME: user, MAIL_PASSWORD: pass, MAIL_HOST: host, MAIL_PORT: port } = process.env;
if (!user || !pass || !host || port) {
// LA SIGUIENTE LÍNEA ARROJA UN ERROR
throw new Error('Especificar MAIL_USERNAME, MAIL_PASSWORD, MAIL_HOST y MAIL_PORT en el archivo .env');
}
const transporter = nodemailer.createTransport({
host,
port: Number(port),
secure: true,
auth: {
user,
pass,
},
});
return transporter;
}
public async sendMail(formValues: string) {
const values: FormValues = JSON.parse(formValues);
const message: SendMailOptions = {...};
await this.transporter.sendMail(message, (err, info) => {
if (err) {
throw err;
}
console.log('Correo electrónico enviado con éxito. Información:\n', info);
});
}
}
Y llamando a la función sendMail
desde la función handler
:
export default async function Handler(req: NextApiRequest, res: NextApiResponse) {
const { body } = req;
try {
const response = await MessageTransporter.sendMail(body); // MessageTransporter es una instancia de MailTransporter
res.status(200).json({ success: true, message: 'OK' });
} catch (error) {
res.json({ success: false, message: 'No se pudo enviar el mensaje' });
}
}
Pero el error arrojado en MailTransporter
no se está capturando en Handler
, en su lugar, recibo el error en mi consola <img src="https://i.imgur.com/E5V310u.png" alt="image">
. Además, en mi navegador recibo un error 500 en mi solicitud POST.
¿Podría explicar qué está sucediendo allí? ¿Por qué el error no se captura dentro del try catch
de handler
?
También, soy bastante nuevo en las clases de JavaScript, así que si tiene algo que decir sobre el diseño de la clase, por favor hágalo.
davy.ai
El problema aquí es que la función
sendMail
de la claseMailTransporter
está lanzando un error pero no está devolviendo nada. La palabra claveawait
se utiliza al llamar a la funciónsendMail
enHandler
, lo que significa que espera que se devuelva una promesa. Dado que la funciónsendMail
no devuelve nada, el bloquetry-catch
enHandler
no puede capturar el error lanzado por la funciónsendMail
.Para solucionar esto, puedes envolver el callback de la función
sendMail
en una Promesa de esta manera:Ahora, la función
sendMail
devolverá una Promesa y eltry-catch
enHandler
debería capturar correctamente cualquier error lanzado porsendMail
.En cuanto al diseño de la clase, no hay nada inherentemente incorrecto con la clase
MailTransporter
. Está manejando correctamente la lógica de transporte de correo electrónico y el manejo de errores. Sin embargo, siempre es bueno modularizar el código tanto como sea posible y separar las responsabilidades. Por ejemplo, podrías tener una clase separada para analizar los valores del formulario y construir el mensaje de correo electrónico. De esta manera, la claseMailTransporter
no tendría que preocuparse por los valores del formulario y podría centrarse únicamente en el envío del correo electrónico.