Я сделал простое приложение, в котором фрагменты файла передаются от клиента к серверу. На стороне сервера я обработал исключения, так что клиенту возвращается мой собственный ответ. Однако когда я генерирую исключение до того, как чтение из потока было завершено, даже если оно перехватывается и возвращается пользовательский ответ, на стороне клиента я все равно получаю необработанное RpcException
со статусом Cancelled
.
public override async Task<UploadFileResponse> UploadFile(
IAsyncStreamReader<UploadFileRequest> requestStream,
ServerCallContext context)
{
try
{
bool moveNext = await requestStream.MoveNext();
using (var stream = System.IO.File.Create($"foo.txt"))
{
while (moveNext)
{
// If something goes wrong here, before the stream has been fully read, an RpcException
// of status Cancelled is caught in the client instead of receiving an UploadFileResponse of
// type 'Failed'. Despite the fact that we catch it in the server and return a Failed response.
await stream.WriteAsync(requestStream.Current.Data.ToByteArray());
moveNext = await requestStream.MoveNext();
throw new Exception();
}
// If something goes wrong here, when the stream has been fully read, we catch it and successfully return
// a response of our own instead of an RpcException.
// throw new Exception();
}
return new UploadFileResponse()
{
StatusCode = UploadStatusCode.Ok
};
}
catch (Exception ex)
{
return new UploadFileResponse()
{
Message = ex.Message,
StatusCode = UploadStatusCode.Failed
};
}
}
Возможно, мой подход к выполнению этой операции неправильный. Я понимаю, почему сервер возвращает исключение Cancelled
RP C, потому что мы действительно отменяем вызов до того, как поток будет полностью прочитан, но я не понимаю, почему он отменяет пользовательский ответ. Может случиться так, что обе обработки придется выполнять на стороне клиента - неудачный ответ и возможное исключение RP C.