function setTransDataFromHttpTriggerResult()

in lib/instrumentation/azure-functions.js [194:264]


function setTransDataFromHttpTriggerResult(trans, hookCtx) {
  if (hookCtx.error) {
    trans.setOutcome(constants.OUTCOME_FAILURE);
    trans.result = 'HTTP 5xx';
    trans.res = {
      statusCode: 500,
    };
    return;
  }

  // Attempt to get what the Azure Functions system will use for the HTTP response
  // data. This is a pain because Azure Functions supports a number of different
  // ways the user can return a response. Part of the handling for this is:
  // https://github.com/Azure/azure-functions-nodejs-library/blob/v3.5.0/src/InvocationModel.ts#L77-L144
  const funcInfo = hookCtx.hookData.funcInfo;
  const result = hookCtx.result;
  const context = hookCtx.invocationContext;
  let httpRes;
  if (funcInfo.hasReturnBinding) {
    httpRes = hookCtx.result;
  } else {
    if (
      result &&
      typeof result === 'object' &&
      result[funcInfo.httpOutputName] !== undefined
    ) {
      httpRes = result[funcInfo.httpOutputName];
    } else if (
      context.bindings &&
      context.bindings[funcInfo.httpOutputName] !== undefined
    ) {
      httpRes = context.bindings[funcInfo.httpOutputName];
    } else if (context.res !== undefined) {
      httpRes = context.res;
    }
  }

  // Azure Functions requires that the HTTP output response value be an 'object',
  // otherwise it errors out the response (statusCode=500) and logs an error:
  //    Stack: Error: The HTTP response must be an 'object' type that can include properties such as 'body', 'status', and 'headers'. Learn more: https://go.microsoft.com/fwlink/?linkid=2112563
  if (typeof httpRes !== 'object') {
    trans.setOutcome(constants.OUTCOME_FAILURE);
    trans.result = 'HTTP 5xx';
    trans.res = {
      statusCode: 500,
    };
    return;
  }

  let statusCode = Number(httpRes.status);
  if (!Number.isInteger(statusCode)) {
    // While https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-http-webhook-trigger
    // suggests the default may be "HTTP 204 No Content", my observation is that
    // 200 is the actual default.
    statusCode = 200;
  }

  if (statusCode < 500) {
    trans.setOutcome(constants.OUTCOME_SUCCESS);
  } else {
    trans.setOutcome(constants.OUTCOME_FAILURE);
  }
  trans.result = 'HTTP ' + statusCode.toString()[0] + 'xx';
  trans.res = {
    statusCode,
    body: httpRes.body,
  };
  if (httpRes.headers && typeof httpRes.headers === 'object') {
    trans.res.headers = httpRes.headers;
  }
}