Express Response.send()抛出TypeError

时间:2018-03-20 01:00:23

标签: node.js typescript express npm

我有这个简单的快递代码:

const api = Router()

api.post('/some-point', async (req, res, next) => {
  const someStuffToSend = await Promise.resolve("hello");
  res.json({ someStuffToSend });
})

它在我的开发环境中运行良好,但在产品上我得到错误:

TypeError: argument entity must be string, Buffer, or fs.Stats
    at etag (/[...]/node_modules/etag/index.js:83:11)
    at generateETag ([...]/node_modules/express/lib/utils.js:280:12)
    at ServerResponse.send ([...]/node_modules/express/lib/response.js:200:17)
    at ServerResponse.json ([...]/node_modules/express/lib/response.js:267:15)
    at api.post (/the/code/above)

我在node_modules/etag/index.js:83:11查看并看到了

if (!isStats && typeof entity !== 'string' && !Buffer.isBuffer(entity)) {
  throw new TypeError('argument entity must be string, Buffer, or fs.Stats')
}

在此代码之前,我添加了一个printf来检查实体的类型:

console.log("Entity contains", entity, "is of type", typeof entity, "with constructor", entity.constructor, "and is it a buffer?", Buffer.isBuffer(entity))

这让我得到了输出:

Entity contains <Buffer 7b 22 70 72 65 64 69 63 74 69 6f 6e 5f 69 64 22 3a 22 63 4b 57 41 64 41 46 43 77 6e 55 43 22 2c 22 69 6e 69 74 69 61 6c 5f 70 72 65 64 69 63 74 69 6f ... > is of type object with constructor function Buffer(arg, encodingOrOffset, length) {
  if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) {
    return new Buffer(arg, encodingOrOffset, length)
  }

  // Common case.
  if (typeof arg === 'number') {
    if (typeof encodingOrOffset === 'string') {
      throw new Error(
        'If encoding is specified then the first argument must be a string'
      )
    }
    return allocUnsafe(this, arg)
  }
  return from(this, arg, encodingOrOffset, length)
} and is it a buffer? false

所以看起来实体是一个缓冲区,但是没有被识别出来。如果我评论测试,它会在不同的位置崩溃

TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be one of type string or Buffer
    at ServerResponse.end (_http_outgoing.js:747:13)
    at ServerResponse.send ([...]/node_modules/express/lib/response.js:221:10)
    at ServerResponse.json ([...]/node_modules/express/lib/response.js:267:15)
    at api.post (/the/code/above)

如果您在/node_modules/express/lib/response.js:221:10处查看

this.end(chunk, encoding);

其中编码来自上面的几行(l.189,我用printf检查过)

chunk = Buffer.from(chunk, encoding)

我可以破解lib来完成这项工作,但我怀疑有一些损坏的node_modules文件夹。但是,即使在rm package-lock.json; rm -rf node_modules; npm i之后错误仍然存​​在。

如何解决这个问题的任何线索都将非常感激。

以下是我的版本号:

  • 节点9.8.0(也尝试使用8.4.0),使用nvm
  • 在本地安装
  • npm 5.6.0
  • express 4.16.3
  • ts-node 5.0.1
  • typescript 2.7.2

修改1

  • 用更简单的
  • 替换异步调用
  • 指定快速版

修改2

我删除了node_modules文件夹,然后npm i逐个删除了包:

npm i aws-sdk body-parser bunyan check-types deepcopy duck-type express fast-csv glob handlebars http-auth md5 moment moment-timezone multer node-stream object-path randomstring

仍然得到同样的错误。

编辑3

添加有关环境的更多信息。

编辑4

好的,想通了。这是一个与ts节点配置相关的问题。 我用

启动我的服务器
ts-node --harmony_async_iteration -r tsconfig-paths/register ./src/index.ts

我的tsconfig.json中包含以下几行:

{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es2017",
    "lib": [ "es2017", "esnext.asynciterable" ],
    "noImplicitAny": true,
    "moduleResolution": "node",
    "sourceMap": true,
    "outDir": "dist",
    "baseUrl": ".",
    "pretty": true,
    "paths": {
      "*": [
        "*", "src/*", "src/types/*",
        "node_modules/*"
      ]
    }
  },
  "include": [ "src/**/*" ]
}

由于命令行中有-r tsconfig-paths/registertsconfig.json中指定的路径已加载,包括"node_modules/*"中的paths['*']

我不确定原因,但看起来这导致node_modules中的lib被加载两次,打破了基于构造函数的类型检查(例如instanceof)。 / p>

问题

我不确定完全理解其原因。有光吗?

1 个答案:

答案 0 :(得分:1)

我对typeorm有一个非常相似的问题,后来对express也有一个相似的问题。提示在this conversation中。我的解决方案是从*摆脱paths