Vercel/NextJS部署在完成无服务器功能之前不会等待通过Azure发送电子邮件

xdnvmnnf  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(111)

我正在尝试在用户注册时发送注册/帐户激活电子邮件。在本地主机上运行时,电子邮件会通过Azure的电子邮件服务正确发送,但Vercel上的实时部署不会发送电子邮件(尽管用户已成功创建/输入数据库)。
已经看到/阅读了关于Vercel托管部署和电子邮件发送问题的其他问题,通常由无服务器函数在接收到响应后返回引起(通常在发送电子邮件之前)。然而,使用Microsoft的Azure电子邮件通信服务,我似乎无法通过await/alphaic函数调用获得正确的行为。还没有看到任何其他修复/因此,我希望看看是否有人可以建议解决这个特定问题。
Link to similar issue
从上面的链接中提取:

  • 如果你在免费层,每个请求必须在10秒内解决(亲其60),
  • Vercel似乎在返回响应后立即终止无服务器函数,也就是说,未完成的副作用将停止运行。

他们只是通过添加一个等待来发送电子邮件,但Azure的特定电子邮件客户端行为已经有了

const poller = await emailClient.beginSend(emailMessage);
const result = await poller.pollUntilDone();

字符串
这应该在返回之前等待整个事情,因此不应该在发送电子邮件之前提前结束无服务器功能。
下面是api/register/route.ts文件中的大部分电子邮件发送代码。

export async function POST(
  request: Request, 
) {
  const connectionString = process.env['COMMUNICATION_SERVICES_CONNECTION_STRING'];
  const emailClient = new EmailClient(connectionString);

  async function main() {
    const emailMessage = {
      senderAddress: "[email protected]",
      content: {
          subject: ``,
          text: ``,
          html: ``,
      },
      recipients: {
          to: [{ address: user.email }], // don't worry this is defined, cut out majority of code above for shortness
      },
    };

    const poller = await emailClient.beginSend(emailMessage);
    const result = await poller.pollUntilDone();
    console.log("Email sent: %s", result);
  }

  main().catch(console.error);

  // setTimeout(() => { return NextResponse.json(user); }, 3000);
  return NextResponse.json(user);
}


我在返回响应之前尝试了一个纯超时缓冲区,因为它似乎可以工作,但它导致了一个错误被抛出并在这里和这个API route. ts的外部调用者中被捕获。
我希望这能让邮件在无服务器函数终止之前发送(它可能会工作),但有错误被抛出的问题
“错误类型错误:无法在eval(webpack-internal:/(sc_server)/./node_modules/next/dist/server/future/route-modules/app-route/module.js:261:61)读取未定义的属性(阅读'headers')”

rur96b6h

rur96b6h1#

最后,需要在main().catch(console.error);之前添加await作为main,这是我在整个POST请求中调用的P2C函数。
原行:

main().catch(console.error);

字符串
修改后的行为:

await main().catch(console.error);


这允许该功能运行,直到电子邮件发送。
对于用户注册,此电子邮件发送逻辑可能需要从注册/将用户添加到数据库的逻辑中分离出来,因为它会导致外部注册模式在等待电子邮件发送时挂起。最好在数据库中创建用户并将模式设置为关闭之后放置此电子邮件发送功能。

axios.post("/api/register", data)
  .then((response) => {
    if (response.data.error) {
      toast.error(response.data.error.message);
    } else {
      toast.success(`Registered! Verify email to activate your account.`, {
        duration: 6000,
      });
      setStep(STEPS.BASICS)
      registerModal.onClose();
      loginModal.onOpen();
    }
  })
  .catch((error) => {
    if (error.response && error.response.data && error.response.data.error) {
      toast.error(error.response.data.error);
    } else {
      toast.error('Registration failed. Please try again.');
    }
  })
  .finally(() => {
    setIsLoading(false);
  });

相关问题