防止 Mongoose 堆栈跟踪错误

Posted

技术标签:

【中文标题】防止 Mongoose 堆栈跟踪错误【英文标题】:Prevent Mongoose stack trace for errors 【发布时间】:2016-06-21 19:22:03 【问题描述】:

Mongoose 会针对转换错误发出堆栈跟踪。我知道如何防止 Mongoose 错误 - 请不要回答如何防止错误。

如何阻止 Mongoose 在生产环境中发出堆栈跟踪错误?

错误:传入的参数必须是 12 字节的单个字符串或 新 ObjectID 处的 24 个十六进制字符的字符串 (c:\proj\fboapp\node_modules\mongoose\node_modules\bson\lib\bson\objectid.js:38:11) 在 c:\proj\fboapp\routes\user\no_auth_user_api_routes.js:135:27 在 Layer.handle [as handle_request] (c:\proj\fboapp\node_modules\express\lib\router\layer.js:95:5) 在 下一个(c:\proj\fboapp\node_modules\express\lib\router\route.js:131:13) 在 Route.dispatch (c:\proj\fboapp\node_modules\express\lib\router\route.js:112:3) 在 Layer.handle [as handle_request] (c:\proj\fboapp\node_modules\express\lib\router\layer.js:95:5) 在 c:\proj\fboapp\node_modules\express\lib\router\index.js:277:22 在 Function.process_params (c:\proj\fboapp\node_modules\express\lib\router\index.js:330:12) 在 下一个(c:\proj\fboapp\node_modules\express\lib\router\index.js:271:10) 在 Function.handle (c:\proj\fboapp\node_modules\express\lib\router\index.js:176:3) 在 路由器(c:\proj\fboapp\node_modules\express\lib\router\index.js:46:12) 在 Layer.handle [as handle_request] (c:\proj\fboapp\node_modules\express\lib\router\layer.js:95:5) 在 修剪前缀 (c:\proj\fboapp\node_modules\express\lib\router\index.js:312:13) 在 c:\proj\fboapp\node_modules\express\lib\router\index.js:280:7 at Function.process_params (c:\proj\fboapp\node_modules\express\lib\router\index.js:330:12) 在 下一个(c:\proj\fboapp\node_modules\express\lib\router\index.js:271:10)

Nodejs v0.12.3 猫鼬 v4.4.3

【问题讨论】:

你真的想这样做吗?这是您的应用程序中的错误,应该修复。但是,如果您仍然想要 - 为该错误类型创建事件并处理它... 为了安全起见,我想防止在生产中向浏览器 api 发出错误。该错误已修复 - 我只是粘贴了错误代码来演示堆栈跟踪。 哦,这实际上是猫鼬中的throw 声明。所以,没有办法“隐藏”它,除了使用try ... catch,据我所知。 顺便说一句,你用的是快递吗?就是这样,express可以很好地处理错误 这是一个模块,github.com/Faleij/mongoose-disable-stack-trace,你可以试试。 【参考方案1】:

一般来说,在代码中添加try-catch 块可能是正确的方法。

这是我的测试代码,代码中没有 try-catch 块,然后阻止堆栈跟踪。参考这个模块mongoose disable stack trace,同时添加some new errors被添加到mongoose中,设置Error.stackTraceLimit0将禁用堆栈跟踪收集。


index.js

const captureStackTrace = Error.captureStackTrace;
const CastError = module.parent.require('mongoose/lib/error/cast');
const VersionError = module.parent.require('mongoose/lib/error/version');
const ValidatorError = module.parent.require('mongoose/lib/error/validator');
const ValidationError = module.parent.require('mongoose/lib/error/validation');
const OverwriteModelError = module.parent.require('mongoose/lib/error/overwriteModel');
const MissingSchemaError = module.parent.require('mongoose/lib/error/missingSchema');
const DivergentArrayError = module.parent.require('mongoose/lib/error/divergentArray');

Error.captureStackTrace = function( that, params) 
    if(that instanceof CastError ||
        that instanceof VersionError ||
        that instanceof ValidatorError ||
        that instanceof ValidationError ||
        that instanceof OverwriteModelError ||
        that instanceof MissingSchemaError ||
        that instanceof DivergentArrayError) 
        Error.stackTraceLimit = 0;
     else if (typeof that !== 'undefined')
        captureStackTrace.apply(Error, arguments);
         


Error.captureStackTrace(new VersionError);

app.js

require('mongoose-disable-stack-trace');
var f = Foo(_id: new ObjectId('adss112'), key: '123'); // invalid ObjectId

输出:

Error: Argument passed in must be a single String of 12 bytes or a string of 24
hex characters
c:\share\node\node_modules\mongoose\node_modules\mongodb\lib\server.js:283
      process.nextTick(function()  throw err; )                                  ^

Error: Argument passed in must be a single String of 12 bytes or a string of 24
hex characters

【讨论】:

显然 Express 有一个默认的错误处理程序,它正在输出到浏览器,因为在我的应用程序中没有指定自定义错误处理程序。指定自定义错误处理程序会覆盖默认的 Express 错误处理程序。默认总是将堆栈跟踪输出到浏览器,但显然自定义处理程序不需要输出堆栈跟踪。 My answer【参考方案2】:

直到我读到ExpressJS error handling documentation page 之前,我一直对为什么在没有错误处理程序的情况下将错误呈现给浏览器感到困惑。

显然有默认错误处理程序,当没有指定错误处理程序时触发。

Express 带有一个内置的错误处理程序,它可以处理任何 应用程序中可能遇到的错误。这个默认 错误处理中间件函数添加在末尾 中间件函数栈。

最佳实践是为生产指定一个自定义错误处理程序,它不会将堆栈跟踪输出到浏览器。默认错误处理程序始终将堆栈跟踪输出到浏览器。

不需要 try-catch 块将未捕获的错误路由到自定义错误处理程序,因为 Express 会自动将未捕获的错误路由到错误处理程序。另请注意:错误处理程序中间件必须指定所有 4 个参数:err, req, res and next

自定义错误处理程序示例:

app.use(function(err, req, res, next) 
        res.send('uncaught error in production');
);

【讨论】:

以上是关于防止 Mongoose 堆栈跟踪错误的主要内容,如果未能解决你的问题,请参考以下文章

Maven:如何防止 exec 插件显示其堆栈跟踪?

在 Spring Boot 应用程序中防止自定义异常的堆栈跟踪日志记录

mongoose基本增删改查

Node.js/Mongoose 上的“版本错误:未找到匹配的文档”错误

Mongoose 不尊重模式并插入错误的数据类型

Node.js / Mongoose上的“VersionError:找不到匹配的文档”错误