Example #1
0
        /// <summary>
        /// Adds the messages to response trailers as a binary byte array.
        /// </summary>
        private static void AddMessagesToResponseTrailers(GrpcServiceBase service, MessageItemCollection?messages)
        {
            if (messages == null || messages.Count == 0)
            {
                return;
            }

            using var ms  = new MemoryStream();
            using var bdw = new BsonDataWriter(ms);
            var js = new JsonSerializer();

            js.Serialize(bdw, new GrpcMessages {
                Messages = messages
            });

            service.Context.ResponseTrailers.Add(GrpcConsts.MessagesHeaderName, ms.ToArray());
        }
Example #2
0
        /// <summary>
        /// Create <see cref="grpc.Status"/> from the <see cref="Exception"/>.
        /// </summary>
        /// <param name="service">The <see cref="GrpcServiceBase"/>.</param>
        /// <param name="exception">The <see cref="Exception"/>.</param>
        /// <returns>The corresponding <see cref="grpc.Status"/>.</returns>
        public static void ThrowRpcExceptionFromException(GrpcServiceBase service, Exception exception)
        {
            if (service == null)
            {
                throw new ArgumentNullException(nameof(service));
            }

            if (exception == null)
            {
                throw new ArgumentNullException(nameof(exception));
            }

            IBusinessException?ex = null;

            // Unwind to a known exception type if we can.
            if (exception is IBusinessException)
            {
                ex = exception as IBusinessException;
            }

            if (ex == null && exception is AggregateException aex)
            {
                if (aex.InnerExceptions.Count == 1 && aex.InnerException is IBusinessException)
                {
                    ex = aex.InnerException as IBusinessException;
                }
            }

            // Where it is not known then "action" as unhandled.
            if (ex != null)
            {
                if (ex.ShouldBeLogged)
                {
                    Diagnostics.Logger.Create <GrpcServiceBase>().LogError(exception, UnhandledExceptionMessage);
                }

                grpc.Status?status = ex.ErrorType switch
                {
                    ErrorType.AuthenticationError => new grpc.Status(grpc.StatusCode.Unauthenticated, exception.Message),
                    ErrorType.AuthorizationError => new grpc.Status(grpc.StatusCode.PermissionDenied, exception.Message),
                    ErrorType.BusinessError => new grpc.Status(grpc.StatusCode.InvalidArgument, exception.Message),
                    ErrorType.ConcurrencyError => new grpc.Status(grpc.StatusCode.Aborted, exception.Message),
                    ErrorType.ConflictError => new grpc.Status(grpc.StatusCode.FailedPrecondition, exception.Message),
                    ErrorType.DuplicateError => new grpc.Status(grpc.StatusCode.AlreadyExists, exception.Message),
                    ErrorType.NotFoundError => new grpc.Status(grpc.StatusCode.NotFound, exception.Message),
                    ErrorType.ValidationError => new grpc.Status(grpc.StatusCode.InvalidArgument, exception.Message),
                    _ => null,
                };

                if (status != null)
                {
                    service.Context.ResponseTrailers.Add(GrpcConsts.ErrorTypeHeaderName, ex.ErrorType.ToString());
                    service.Context.ResponseTrailers.Add(GrpcConsts.ErrorCodeHeaderName, ((int)ex.ErrorType).ToString(System.Globalization.CultureInfo.InvariantCulture));

                    if (ex is ValidationException vex)
                    {
                        AddMessagesToResponseTrailers(service, vex.Messages);
                    }

                    throw new grpc.RpcException(status.Value);
                }
            }

            if (ex == null)
            {
                Diagnostics.Logger.Create <GrpcServiceBase>().LogError(exception, UnhandledExceptionMessage);
            }

            throw new grpc.RpcException(new grpc.Status(UnhandledExceptionStatusCode, IncludeUnhandledExceptionInResponse ? exception.ToString() : UnhandledExceptionMessage));
        }