Clarifai 预测 API - 无法使用 res.json return 错误响应

Clarifai Predict API - Cannot return error response using res.json

我在 node/express 环境中的另一个 API 中使用 Clarifai 的预测 API,如下面的代码所示。

如果 Clarifai 的 API return 响应成功,我可以 res.json 我的 API 中收到的数据并在 Postman 中查看。

但是,如果出现错误,Postman 不会显示任何内容,它只会一直等待响应。

我将其隔离为以下原因: res.json 设法 return json 格式的成功响应,但由于某些原因,它 hangs/does 不是 return 在处理错误响应时的输出。

不清楚原因。

res.send 无法使用错误响应 either.The 我唯一能做的就是 console.log 它。

const callClarifaiApi = (req, res) => {
    app.models
        .predict(Clarifai.FACE_DETECT_MODEL, req.body.input)
        .then(data => {
            console.log("Response:", data);
            res.json(data);
        })
        .catch((err) => {
            console.log("Error:", err);
            res.status(400).json(err);
        })
};

这是控制台记录的成功响应

{ status:
   { code: 10000,
     description: 'Ok',
     req_id: 'b51531471ae2404e810f2efd06a57027' },
  outputs:
   [ { id: 'a83241abd8ec4117b6c747775e46fa5c',
       status: [Object],
       created_at: '2019-08-07T12:24:03.174628276Z',
       model: [Object],
       input: [Object],
       data: [Object] } ],
  rawData:
   { status:
      { code: 10000,
        description: 'Ok',
        req_id: 'b51531471ae2404e810f2efd06a57027' },
     outputs: [ [Object] ] } }

这是控制台记录的错误响应

{ status: 400,
  statusText: 'Bad Request',
  headers:
   { 'access-control-allow-headers':
      'Content-Type,Accept,X-Requested-With,Content-Type,Accept-Encoding,X-CSRF-Token,Authorization,X-Clarifai-Application-Id,X-Clarifai-REST-API-Key,X-Clarifai-Session-Token,X-Clarifai-Client,X-Clarifai-Site,X-RapidAPI-User,x-clarifai-request-id-prefix',
     'access-control-allow-methods': 'GET,HEAD,POST,PUT,PATCH,OPTIONS,DELETE',
     'access-control-allow-origin': '*',
     'content-type': 'application/json; charset=UTF-8',
     date: 'Wed, 07 Aug 2019 12:39:32 GMT',
     server: 'nginx',
     'content-length': '98',
     connection: 'Close' },
  config:
   { transformRequest: { '0': [Function: transformRequest] },
     transformResponse: { '0': [Function: transformResponse] },
     headers:
      { Accept: 'application/json, text/plain, */*',
        'Content-Type': 'application/json;charset=utf-8',
        Authorization: 'Key XXXXXXXXXXXXXXX',
        'X-Clarifai-Client': 'js:2.9.0',
        'User-Agent': 'axios/0.11.1',
        'Content-Length': 46 },
     timeout: 0,
     xsrfCookieName: 'XSRF-TOKEN',
     xsrfHeaderName: 'X-XSRF-TOKEN',
     maxContentLength: -1,
     validateStatus: [Function: validateStatus],
     method: 'post',
     url:
      'https://api.clarifai.com/v2/models/a403429f2ddf4b49b307e318f00e528b/outputs',
     data: '{"inputs":[{"data":{"image":{"base64":"a"}}}]}',
     withCredentials: undefined },
  request:
   ClientRequest {
     _events:
      [Object: null prototype] {
        error: [Function: handleRequestError],
        prefinish: [Function: requestOnPrefinish] },
     _eventsCount: 2,
     _maxListeners: undefined,
     output: [],
     outputEncodings: [],
     outputCallbacks: [],
     outputSize: 0,
     writable: true,
     _last: true,
     chunkedEncoding: false,
     shouldKeepAlive: false,
     useChunkedEncodingByDefault: true,
     sendDate: false,
     _removedConnection: false,
     _removedContLen: false,
     _removedTE: false,
     _contentLength: 46,
     _hasBody: true,
     _trailer: '',
     finished: true,
     _headerSent: true,
     socket:
      TLSSocket {
        _tlsOptions: [Object],
        _secureEstablished: true,
        _securePending: false,
        _newSessionPending: false,
        _controlReleased: true,
        _SNICallback: null,
        servername: 'api.clarifai.com',
        alpnProtocol: false,
        authorized: true,
        authorizationError: null,
        encrypted: true,
        _events: [Object],
        _eventsCount: 8,
        connecting: false,
        _hadError: false,
        _handle: [TLSWrap],
        _parent: null,
        _host: 'api.clarifai.com',
        _readableState: [ReadableState],
        readable: true,
        _maxListeners: undefined,
        _writableState: [WritableState],
        writable: false,
        allowHalfOpen: false,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: undefined,
        _server: null,
        ssl: [TLSWrap],
        _requestCert: true,
        _rejectUnauthorized: true,
        parser: null,
        _httpMessage: [Circular],
        [Symbol(res)]: [TLSWrap],
        [Symbol(asyncId)]: 129,
        [Symbol(lastWriteQueueSize)]: 0,
        [Symbol(timeout)]: null,
        [Symbol(kBytesRead)]: 0,
        [Symbol(kBytesWritten)]: 0,
        [Symbol(connect-options)]: [Object] },
     connection:
      TLSSocket {
        _tlsOptions: [Object],
        _secureEstablished: true,
        _securePending: false,
        _newSessionPending: false,
        _controlReleased: true,
        _SNICallback: null,
        servername: 'api.clarifai.com',
        alpnProtocol: false,
        authorized: true,
        authorizationError: null,
        encrypted: true,
        _events: [Object],
        _eventsCount: 8,
        connecting: false,
        _hadError: false,
        _handle: [TLSWrap],
        _parent: null,
        _host: 'api.clarifai.com',
        _readableState: [ReadableState],
        readable: true,
        _maxListeners: undefined,
        _writableState: [WritableState],
        writable: false,
        allowHalfOpen: false,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: undefined,
        _server: null,
        ssl: [TLSWrap],
        _requestCert: true,
        _rejectUnauthorized: true,
        parser: null,
        _httpMessage: [Circular],
        [Symbol(res)]: [TLSWrap],
        [Symbol(asyncId)]: 129,
        [Symbol(lastWriteQueueSize)]: 0,
        [Symbol(timeout)]: null,
        [Symbol(kBytesRead)]: 0,
        [Symbol(kBytesWritten)]: 0,
        [Symbol(connect-options)]: [Object] },
     _header:
      'POST /v2/models/a403429f2ddf4b49b307e318f00e528b/outputs HTTP/1.1\r\nAccept: application/json, text/plain, */*\r\nContent-Type: application/json;charset=utf-8\r\nAuthorization: Key xxxxxxxxxxxxxxxxxxxxxxxx\r\nX-Clarifai-Client: js:2.9.0\r\nUser-Agent: axios/0.11.1\r\nContent-Length: 46\r\nHost: api.clarifai.com\r\nConnection: close\r\n\r\n',
     _onPendingData: [Function: noopPendingOutput],
     agent:
      Agent {
        _events: [Object],
        _eventsCount: 1,
        _maxListeners: undefined,
        defaultPort: 443,
        protocol: 'https:',
        options: [Object],
        requests: {},
        sockets: [Object],
        freeSockets: {},
        keepAliveMsecs: 1000,
        keepAlive: false,
        maxSockets: Infinity,
        maxFreeSockets: 256,
        maxCachedSessions: 100,
        _sessionCache: [Object] },
     socketPath: undefined,
     timeout: undefined,
     method: 'POST',
     path: '/v2/models/a403429f2ddf4b49b307e318f00e528b/outputs',
     _ended: true,
     res:
      IncomingMessage {
        _readableState: [ReadableState],
        readable: false,
        _events: [Object],
        _eventsCount: 2,
        _maxListeners: undefined,
        socket: [TLSSocket],
        connection: [TLSSocket],
        httpVersionMajor: 1,
        httpVersionMinor: 1,
        httpVersion: '1.1',
        complete: true,
        headers: [Object],
        rawHeaders: [Array],
        trailers: {},
        rawTrailers: [],
        aborted: false,
        upgrade: false,
        url: '',
        method: null,
        statusCode: 400,
        statusMessage: 'Bad Request',
        client: [TLSSocket],
        _consuming: false,
        _dumped: false,
        req: [Circular],
        fetchedUrls: [Array] },
     aborted: undefined,
     timeoutCb: null,
     upgradeOrConnect: false,
     parser: null,
     maxHeadersCount: null,
     [Symbol(isCorked)]: false,
     [Symbol(outHeadersKey)]:
      [Object: null prototype] {
        accept: [Array],
        'content-type': [Array],
        authorization: [Array],
        'x-clarifai-client': [Array],
        'user-agent': [Array],
        'content-length': [Array],
        host: [Array] } },
  data:
   { status:
      { code: 11102,
        description: 'Invalid request',
        details: 'Malformed or invalid request' } } }

Express 无法序列化错误对象。试试这样发送:

res.status(400).json({error:err.statusText});