in core/controller/src/main/scala/org/apache/openwhisk/core/controller/Actions.scala [280:330]
private def doInvoke(user: Identity,
actionWithMergedParams: WhiskActionMetaData,
payload: Option[JsObject],
blocking: Boolean,
waitOverride: FiniteDuration,
result: Boolean)(implicit transid: TransactionId): RequestContext => Future[RouteResult] = {
val waitForResponse = if (blocking) Some(waitOverride) else None
onComplete(invokeAction(user, actionWithMergedParams, payload, waitForResponse, cause = None)) {
case Success(Left(activationId)) =>
// non-blocking invoke or blocking invoke which got queued instead
respondWithActivationIdHeader(activationId) {
complete(Accepted, activationId.toJsObject)
}
case Success(Right(activation)) =>
val response = activation.response.result match {
case Some(JsArray(elements)) =>
JsArray(elements)
case _ =>
if (result) activation.resultAsJson else activation.toExtendedJson()
}
respondWithActivationIdHeader(activation.activationId) {
if (activation.response.isSuccess) {
complete(OK, response)
} else if (activation.response.isApplicationError) {
// actions that result is ApplicationError status are considered a 'success'
// and will have an 'error' property in the result - the HTTP status is OK
// and clients must check the response status if it exists
// NOTE: response status will not exist in the JSON object if ?result == true
// and instead clients must check if 'error' is in the JSON
// PRESERVING OLD BEHAVIOR and will address defect in separate change
complete(BadGateway, response)
} else if (activation.response.isContainerError) {
complete(BadGateway, response)
} else {
complete(InternalServerError, response)
}
}
case Failure(t: RecordTooLargeException) =>
logging.debug(this, s"[POST] action payload was too large")
terminate(PayloadTooLarge)
case Failure(RejectRequest(code, message)) =>
logging.debug(this, s"[POST] action rejected with code $code: $message")
terminate(code, message)
case Failure(t: LoadBalancerException) =>
logging.error(this, s"[POST] failed in loadbalancer: ${t.getMessage}")
terminate(ServiceUnavailable)
case Failure(t: Throwable) =>
logging.error(this, s"[POST] action activation failed: ${t.getMessage}")
terminate(InternalServerError)
}
}