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

Deno调用bat脚本后出现未捕获ForbiddenError问题求助

Deno调用bat程序后未捕获ForbiddenError的排查与解决

问题描述

在Deno处理GET请求时调用bat脚本,脚本运行完成后日志出现[uncaught application error]: ForbiddenError - Forbidden错误:

  • 错误仅在等待程序输出完成时触发
  • 本地try-catch无法捕获该异常
  • 实际业务流程正常执行,仅在执行完毕后打印错误日志
  • 已使用--allow-all参数启动Deno,仍出现权限相关报错

代码示例:

try {
    const url = new URL(ctx.request.url);
    const param1 = url.searchParams.get("p1");
    const param2 = url.searchParams.get("p2");
  
    const runReportBat = [
        Deno.cwd(),
        "..",
        "folder1",
        "run_r.bat",
      ].join("\\");
  
    
    const command = new Deno.Command(runReportBat, {
      args: [param1, param2],
      stdout: "piped",
      stderr: "piped",
    });


    const { code, stdout, stderr } = await command.output();

    ctx.response.body = { 
      status: "success"
    };
  } catch (err) {
    ctx.response.status = 500;
    ctx.response.body = { error: err.message };
  }

可能原因

  1. 错误发生在请求处理后的框架阶段:你的try-catch仅覆盖了请求处理的同步/异步代码,若使用Oak等Web框架,错误可能来自框架后续的响应处理环节(比如安全中间件校验、响应资源清理),这些阶段的异常不会被局部try-catch捕获。
  2. 子进程输出流的隐性权限问题:虽然command.output()会自动关闭流,但某些场景下残留的流资源可能触发Deno内部的权限检查,尤其是在旧版本Deno中。
  3. 框架内置安全校验:部分Web框架的中间件(如CORS、CSRF校验)可能在特定条件下抛出ForbiddenError,未被全局错误处理捕获。

解决方法

1. 添加全局异常捕获定位错误来源

在应用入口处添加全局监听,捕获未处理的异常,明确错误的触发栈:

// 捕获未处理的Promise拒绝
addEventListener("unhandledrejection", (event) => {
  console.error("全局未处理拒绝:", event.reason);
  console.error("调用栈:", event.reason.stack);
});

// 捕获未处理的同步错误
addEventListener("error", (event) => {
  console.error("全局未捕获错误:", event.error);
  console.error("调用栈:", event.error.stack);
});

2. 显式处理子进程输出并排查

将子进程的stdout/stderr转换为字符串,同时排查子进程是否有异常输出:

const { code, stdout, stderr } = await command.output();
// 解码输出内容
const stdoutStr = new TextDecoder().decode(stdout);
const stderrStr = new TextDecoder().decode(stderr);
// 打印子进程输出,排查是否有异常
console.log("子进程标准输出:", stdoutStr);
console.log("子进程错误输出:", stderrStr);

3. 添加框架全局错误处理中间件

如果使用Oak等框架,添加全局错误处理中间件,覆盖框架阶段的异常:

import { Application, Router, isHttpError } from "https://deno.land/x/oak/mod.ts";

const app = new Application();

// 全局错误处理中间件
app.use(async (ctx, next) => {
  try {
    await next();
  } catch (err) {
    if (isHttpError(err)) {
      ctx.response.status = err.status;
      ctx.response.body = { error: err.message };
    } else {
      ctx.response.status = 500;
      ctx.response.body = { error: "Internal Server Error" };
      console.error("未处理错误:", err);
    }
  }
});

// 你的路由逻辑
const router = new Router();
router.get("/your-endpoint", (ctx) => {
  // 原请求处理代码
});

app.use(router.routes());
app.use(router.allowedMethods());

await app.listen({ port: 8000 });

4. 升级Deno到最新稳定版

运行以下命令升级Deno,排除版本bug导致的异常:

deno upgrade

内容的提问来源于stack exchange,提问作者Guillermo Gomez Almeida

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.01 17:43:11