'use strict'

const process = require('process')
const { inspect } = require('util')

const { logEvent } = require('../log')
const { createPb } = require('../errors')

// Error handling for all failures that are process-related
// If a single process might start two instances of the server, each instance
// will collect the warnings of all the instances.
// Note that process events fired that do not belong to autoserver might be
// caught as well.
const processErrorHandler = function({ config }) {
  process.on('unhandledRejection', unhandledHandler.bind(null, config))
  process.on('rejectionHandled', rejectionHandledHandler.bind(null, config))
  process.on('warning', warningHandler.bind(null, config))
}

const unhandledHandler = async function(config, value) {
  const { message, innererror } = getUnhandledProps(value)

  await emitProcessEvent({ message, innererror, config })
}

const getUnhandledProps = function(value) {
  if (value instanceof Error) {
    return { message: UNHANDLED_MESSAGE, innererror: value }
  }

  return { message: `${UNHANDLED_MESSAGE} with value: ${value}` }
}

const UNHANDLED_MESSAGE = 'A promise was rejected and not handled right away'

const rejectionHandledHandler = async function(config, promise) {
  const message = `A promise was rejected but handled too late: ${inspect(
    promise,
  )}`

  await emitProcessEvent({ message, config })
}

const warningHandler = async function(config, error) {
  const { message, code, detail } = error
  const nextLine = [code, detail]
    .filter(string => string !== undefined)
    .join(':')
  const messageA = `${message}\n${nextLine}`

  await emitProcessEvent({ message: messageA, innererror: error, config })
}

// Report process problems as events with event 'failure'
const emitProcessEvent = async function({ message, innererror, config }) {
  const error = createPb(message, { reason: 'ENGINE', innererror })

  await logEvent({
    event: 'failure',
    phase: 'process',
    params: { error },
    config,
  })
}

module.exports = {
  processErrorHandler,
}

@@ -560,32 +560,109 @@
 (null, config))%0A
+  process.on('multipleResolves', multipleResolvesHandler.bind(null, config))%0A
   process.on('re
@@ -851,23 +851,22 @@
 const %7B 
-message
+suffix
 , innere
@@ -881,29 +881,422 @@
  get
-UnhandledProps(value)
+PromiseValue(value)%0A  const message = %60A promise was rejected$%7Bsuffix%7D and not handled right away%60%0A%0A  await emitProcessEvent(%7B message, innererror, config %7D)%0A%7D%0A%0A// eslint-disable-next-line max-params%0Aconst multipleResolvesHandler = async function(config, type, promise, value) %7B%0A  const %7B suffix, innererror %7D = getPromiseValue(value)%0A  const message = %60A promise was $%7Btype%7Dd$%7Bsuffix%7D after being already settled%60
 %0A%0A  
@@ -1367,22 +1367,20 @@
  get
-UnhandledProps
+PromiseValue
  = f
@@ -1445,34 +1445,18 @@
 n %7B 
-message: UNHANDLED_MESSAGE
+suffix: ''
 , in
@@ -1493,38 +1493,17 @@
 n %7B 
-message: %60$%7BUNHANDLED_MESSAGE%7D
+suffix: %60
  wit
@@ -1513,18 +1513,18 @@
 alue
-:
  
+'
 $%7Bvalue%7D
 %60 %7D%0A
@@ -1523,94 +1523,16 @@
 lue%7D
+'
 %60 %7D%0A%7D%0A%0A
-const UNHANDLED_MESSAGE = 'A promise was rejected and not handled right away'%0A%0A
 cons

Add `multipleResolves` event handler