Почему необработанный отказ срабатывает случайно, начиная с одного и того же входа? - PullRequest
0 голосов
/ 21 октября 2019

Я делаю веб-приложение. Это приложение представляет собой ленту новостей, которая позволяет пользователю фильтровать информацию изо дня в день. Каждый раз, когда пользователь меняет день, веб-интерфейс вызывает API-интерфейс сервера. Этот API хорошо работает с другим входом (даже с отклонением в качестве вывода). После определенного количества запросов Nodejs больше не может поймать отклонение и запускает unhandledRejection, которое регистрирует ошибки и приводит к сбою сервера API. Почему это происходит, даже если я ловлю все обещания?

Я использую Nodejs v10.16.3, hapi v18.3.2, mongoose v5.6.13 и bluebird 3.7.1.

// This is how my api handler looks like
module.exports = () => {
  return new Promise((resolve, reject) => {
    promise1()
      .then((res) => {
        return promise2(res)
      })
      .then((res) => {
        return resolve(res)
      })
      .catch((err) => {
        return reject(err)
      })
  })
}

const promise1 = () => {
  return new Promise((resolve, reject) => {
    MongoSchema.aggregate(query)
      , (err, res) => {
        if (err) {
          return reject(new Error(err))
        }
        return resolve(res)
      })
  })
}

const promise2 = (params) => {
  return new Promise((resolve, reject) => {
    const promisesToAll1 = []
    const promisestoAll2 = []

for (let index = 0; index < params.length; index++) {
      promisesToAll1.push( aPromise() ) // see aPromise method below
      promisestoAll2.push( aPromise() )
    }

    return Promise.all(promisesToAll1)
      .then((res) => {
         return Promise.all(promisestoAll2)
      })
      .then((res) => {
        resolve(res)
      }).catch((err) => {
        reject(err)
      })
  })
}
/** In a separated module (monge.js) **/
module.exports.exec = (query) => {
  if (query instanceof Promise) {
    return query
  } else {
    return query.exec()
  }
}


module.exports.aPromise = (query, message) => {
  return new Promise((resolve, reject) => {
    return module.exports.exec(query).then((res) => {
      if ((!res) || (res && 'length' in res && res.length !== 1)) {
        throw (new Error(message))
      }
      return resolve(res)
    }).catch((err) => {
      reject(err)
    })
  })
}

Необработанное отклонение в другом модуле

process.on('unhandledRejection', (reason, promise) => {
  const promiseMessage = JSON.stringify(promise)
  console.error(' Unhandled Rejection at: ' + promiseMessage + ', reason: ' + reason)
  fs.writeFileSync('logs/error.log', ` Unhandled Rejection at: ${promise}, reason: ${reason})`)
  process.exit(1)
// eslint-disable-next-line func-call-spacing
})

Отслеживание стека при необработанном отклонении: (с использованием Chrome DevTools)

process.on (server.js:203)
emit (events.js:198)
(anonymous) (debuggability.js:285)
activeFireEvent (debuggability.js:328)
fireRejectionEvent (debuggability.js:730)
Promise._notifyUnhandledRejection (debuggability.js:117)
unhandledRejectionCheck (debuggability.js:39)
ontimeout (timers.js:436)
tryOnTimeout (timers.js:300)
listOnTimeout (timers.js:263)
processTimers (timers.js:223)
Timeout (async)
init (internal/inspector_async_hook.js:27)
emitInitNative (internal/async_hooks.js:137)
emitInitScript (internal/async_hooks.js:336)
initAsyncResource (internal/timers.js:50)
Timeout (internal/timers.js:82)
setTimeout (timers.js:414)
deferUnhandledRejectionCheck (debuggability.js:76)
Promise._ensurePossibleRejectionHandled (debuggability.js:97)
Promise._reject (promise.js:694)
Promise._rejectCallback (promise.js:509)
(anonymous) (promise.js:521)
module.exports.exec.then.catch (monge.js:32) <--------
tryCatcher (util.js:16)
Promise._settlePromiseFromHandler (promise.js:547)
Promise._settlePromise (promise.js:604)
Promise._settlePromise0 (promise.js:649)
Promise._settlePromises (promise.js:725)
_drainQueueStep (async.js:93)
_drainQueue (async.js:86)
Async._drainQueues (async.js:102)
Async.drainQueues (async.js:15)
runCallback (timers.js:705)
tryOnImmediate (timers.js:676)
processImmediate (timers.js:658)
Immediate (async)
init (internal/inspector_async_hook.js:27)
emitInitNative (internal/async_hooks.js:137)
emitInitScript (internal/async_hooks.js:336)
initAsyncResource (internal/timers.js:50)
Immediate (timers.js:722)
setImmediate (timers.js:774)
schedule (schedule.js:12)
Async._queueTick (async.js:111)
AsyncSettlePromises (async.js:76)
Promise._fulfill (promise.js:675)
Promise._resolveCallback (promise.js:466)
(anonymous) (promise.js:519)
(anonymous) (utils.js:282)
model.hooks.execPost (aggregate.js:974)
(anonymous) (index.js:135)
_tickCallback (internal/process/next_tick.js:61)
TickObject (async)
init (internal/inspector_async_hook.js:27)
emitInitNative (internal/async_hooks.js:137)
emitInitScript (internal/async_hooks.js:336)
TickObject (internal/process/next_tick.js:86)
nextTick (internal/process/next_tick.js:117)
Kareem.execPost (index.js:134)
cursor.toArray (aggregate.js:969)
result (utils.js:410)
executeCallback (utils.js:402)
handleCallback (utils.js:128)
cursor.close (cursor_ops.js:224)
handleCallback (utils.js:128)
completeClose (cursor.js:898)
Cursor.close (cursor.js:917)
cursor._next (cursor_ops.js:224)
handleCallback (cursor.js:204)
_setCursorNotifiedImpl (cursor.js:426)
self._endSession (cursor.js:434)
Cursor._endSession (cursor.js:195)
Cursor._endSession (cursor.js:231)
_setCursorNotifiedImpl (cursor.js:434)
setCursorNotified (cursor.js:426)
done (cursor.js:650)
queryCallback (cursor.js:701)
(anonymous) (pool.js:397)
_tickCallback (internal/process/next_tick.js:61)
TickObject (async)
init (internal/inspector_async_hook.js:27)
emitInitNative (internal/async_hooks.js:137)
emitInitScript (internal/async_hooks.js:336)
TickObject (internal/process/next_tick.js:86)
nextTick (internal/process/next_tick.js:117)
handleOperationCallback (pool.js:396)
(anonymous) (pool.js:451)
emit (events.js:198)
processMessage (connection.js:364)
(anonymous) (connection.js:533)
emit (events.js:198)
addChunk (_stream_readable.js:288)
readableAddChunk (_stream_readable.js:269)
Readable.push (_stream_readable.js:224)
onStreamRead (internal/stream_base_commons.js:94)
...