You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义域名访问Heroku容器化Express应用报500错误排查及优化

Heroku自定义域名访问Express应用返回500错误及错误处理优化方案

问题场景

我在Heroku上部署了一个容器化Express应用,通过Heroku默认域名(如myapp.herokuapp.com)访问一切正常,但使用添加的自定义域名访问时返回500错误,不确定DNS是否有变更。访问https://example.com/swagger/时只能看到无意义的错误提示。

应用代码片段

(async () => {
    try {
        const app = express();

        // 各类中间件配置...

        RegisterRoutes(app);

        app.use("/", express.static("public"));

        app.use(["/swagger"], swaggerUi.serve, swaggerUi.setup(Swagger));
        app.use((err: unknown, _: ExRequest, res: ExResponse, next: NextFunction): ExResponse | void => {
            console.error("ERROR:", JSON.stringify(err));
            if (err instanceof Error) {
                return res.status(500).json({message: "Internal Server Error"});
            }
            next();
        });

        app.use((_req, res: ExResponse) => {
            res.status(404).send({message: "Not Found"});
        });

        app.listen(process.env.PORT, () => {
            console.log(`Server is listening on port ${process.env.PORT}!`);
        });
    } catch (error) {
        console.error(error);
    }
})();

相关日志

2023-02-14T00:50:36.125462+00:00 heroku[router]: at=info method=GET path="/swagger/" host=example.com request_id=... fwd="..." dyno=web.1 connect=0ms service=84ms status=500 bytes=371 protocol=https
2023-02-14T00:50:37.878043+00:00 app[web.1]: ERROR: {}

更新情况

清除Chrome缓存后应用突然恢复正常,但我确定没创建过Cookie,好奇Chrome的缓存能力到底有多强。

错误处理逻辑优化建议

  • 修复错误日志无效问题:当前用JSON.stringify(err)会把带非枚举属性(如stack)的Error对象序列化为{},完全丢失错误信息。改成直接打印错误对象或提取关键字段:
    console.error("ERROR:", err);
    // 或者结构化日志便于排查
    console.error("ERROR:", {
      message: err instanceof Error ? err.message : String(err),
      stack: err instanceof Error ? err.stack : undefined,
      requestHost: req.get("Host")
    });
    
  • 增强500响应的调试性:生产环境返回通用提示,非生产环境附带错误详情:
    if (err instanceof Error) {
      const response = { message: "Internal Server Error" };
      if (process.env.NODE_ENV !== "production") {
        response.details = err.message;
        response.stack = err.stack;
      }
      return res.status(500).json(response);
    }
    
  • 捕获Swagger配置异常:Swagger UI初始化可能因配置文件问题抛出错误,单独包裹try-catch避免影响全局:
    try {
      app.use(["/swagger"], swaggerUi.serve, swaggerUi.setup(Swagger));
    } catch (swaggerErr) {
      console.error("Swagger初始化失败:", swaggerErr);
      app.use(["/swagger"], (req, res) => {
        res.status(500).json({ 
          message: "Swagger服务不可用",
          error: process.env.NODE_ENV !== "production" ? swaggerErr.message : undefined 
        });
      });
    }
    
  • 排查自定义域名潜在问题:即使缓存恢复,仍需确认:
    • DNS记录是否正确(CNAME指向herokudns.com,或A记录匹配Heroku提供的IP)
    • Heroku控制台中自定义域名是否已完成验证
    • 应用是否依赖Host请求头,可添加中间件打印该字段:
      app.use((req, res, next) => {
        console.log("请求Host:", req.get("Host"));
        next();
      });
      

内容的提问来源于stack exchange,提问作者Viktor Stolbin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 16:20:38