execute method

Future<BloomRpcServerResponse> execute(
  1. BloomRpcServerContext context,
  2. dynamic rawInput
)

Executes this binding against context with raw input rawInput.

Implementation

Future<BloomRpcServerResponse> execute(
  BloomRpcServerContext context,
  dynamic rawInput,
) async {
  try {
    final TInput typedInput;
    if (contract.decodeInput != null) {
      typedInput = contract.decodeInput!(rawInput);
    } else if (rawInput is TInput) {
      typedInput = rawInput;
    } else if (rawInput == null && null is TInput) {
      typedInput = null as TInput;
    } else {
      typedInput = rawInput as TInput;
    }

    final result = await handler(context, typedInput);

    final dynamic encodedOutput;
    if (contract.encodeOutput != null) {
      encodedOutput = contract.encodeOutput!(result);
    } else {
      encodedOutput = result;
    }

    return BloomRpcServerResponse.ok(encodedOutput);
  } catch (e) {
    if (e is BloomRpcHttpException) {
      return BloomRpcServerResponse(
        statusCode: e.statusCode,
        body: e.responseBody,
      );
    }
    // A handler that throws BloomRpcValidationErrors is reporting bad INPUT,
    // not a server fault, so it must surface as 422 rather than being folded
    // into the generic 500 below. The shape emitted here is the same one
    // BloomRpcValidationErrors.fromResponse parses on the client, so a thrown
    // error round-trips back into a typed BloomRpcValidationErrors.
    if (e is BloomRpcValidationErrors) {
      return BloomRpcServerResponse.validationError({
        'errors': e.fieldErrors,
        if (e.nonFieldErrors.isNotEmpty) 'non_field_errors': e.nonFieldErrors,
      });
    }
    return BloomRpcServerResponse.serverError(e.toString());
  }
}