Суть вопроса такова - есть шлюз куда приходит запрос, далее он вызывает необходимый сервис
В шлюзе есть глобальный перехватчик исключений
Есть сервис, в котором выбрасывается исключение
Исключениеpublic class RequiredPropertyIsNullOrEmptyException : RpcException
{
private string _requestId;
private string _originalRequestId;
public string RequestId
{
get { return _requestId; }
private set { _requestId = value; }
}
public string? OriginalRequestId
{
get { return _originalRequestId; }
private set { _originalRequestId = value; }
}
/// <summary>
/// Конструктор ошибки
/// </summary>
/// <param name="status">Статус ошибки</param>
/// <param name="requestId">Уникальный идентификатор запроса, в котором произошла ошибка</param>
/// <param name="originalRequestId">Уникальный идентификатор запроса из внешней системы</param>
/// <param name="trailers">Клеймсы</param>
public RequiredPropertyIsNullOrEmptyException(Status status, string requestId, string? originalRequestId) : base(status)
{
_requestId = requestId;
_originalRequestId = originalRequestId ?? string.Empty;
}
}
В самом сервисе оно содержит информацию и поля и оно спокойно гуляет по сервису, однако, выходя за контекст этого сервиса и возвращаясь в шлюз что-то меняет исключение на базовый
RpcException
, соответственно стак трейс и данные теряются, но, передается
Status
и я могу туда пробросить один Response Trailer (видимо там ограничение на 3 элемента стоит, ибо, если их больше 3 - grpc отдает уже ответ 500), но, не хотелось бы туда засовывать огромный json и потом его разбирать.
Собственно, почему это происходит? И как с этим бороться?
p.s. я знаю что у grpc всего одно исключение
Сам интерцептрpublic class GrpcErrorHandler : Interceptor
{
public override async Task<TResponse> UnaryServerHandler<TRequest, TResponse>(
TRequest request,
ServerCallContext context,
UnaryServerMethod<TRequest, TResponse> continuation)
{
try
{
return await continuation(request, context);
}
catch (Exception e)
{
switch (e)
{
case RequiredPropertyIsNullOrEmptyException requiredPropertyIsNullOrEmptyException:
context.ResponseTrailers.Add(new Metadata.Entry("requestId", requiredPropertyIsNullOrEmptyException?.Data?["requestId"]?.ToString() ?? ""));
context.ResponseTrailers.Add(new Metadata.Entry("originalRequestId", requiredPropertyIsNullOrEmptyException?.Data?["originalRequestId"]?.ToString() ?? "")); //почему-то есть в контексте сервиса, но, выходя за рамки - теряется.
throw new RequiredPropertyIsNullOrEmptyException(requiredPropertyIsNullOrEmptyException!.Status, requiredPropertyIsNullOrEmptyException?.Data?["requestId"]?.ToString() ?? "", requiredPropertyIsNullOrEmptyException?.Data?["originalRequestId"]?.ToString());
}
throw;
}
}
}