thrift/lib/netstd/Thrift/TApplicationException.cs
Jens Geyer dce229911c THRIFT-5210 further refactoring and performance optimizations
Client: netstd
Patch: Jens Geyer

This closes #2146
2020-05-17 22:34:10 +02:00

148 lines
5.3 KiB
C#

// Licensed to the Apache Software Foundation(ASF) under one
// or more contributor license agreements.See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
using System.Threading;
using System.Threading.Tasks;
using Thrift.Protocol;
using Thrift.Protocol.Entities;
using Thrift.Protocol.Utilities;
namespace Thrift
{
// ReSharper disable once InconsistentNaming
public class TApplicationException : TException
{
public enum ExceptionType
{
Unknown,
UnknownMethod,
InvalidMessageType,
WrongMethodName,
BadSequenceId,
MissingResult,
InternalError,
ProtocolError,
InvalidTransform,
InvalidProtocol,
UnsupportedClientType
}
private const int MessageTypeFieldId = 1;
private const int ExTypeFieldId = 2;
public ExceptionType Type { get; private set; }
public TApplicationException()
{
}
public TApplicationException(ExceptionType type)
{
Type = type;
}
public TApplicationException(ExceptionType type, string message)
: base(message, null) // TApplicationException is serializable, but we never serialize InnerException
{
Type = type;
}
public static async ValueTask<TApplicationException> ReadAsync(TProtocol inputProtocol, CancellationToken cancellationToken)
{
string message = null;
var type = ExceptionType.Unknown;
await inputProtocol.ReadStructBeginAsync(cancellationToken);
while (true)
{
var field = await inputProtocol.ReadFieldBeginAsync(cancellationToken);
if (field.Type == TType.Stop)
{
break;
}
switch (field.ID)
{
case MessageTypeFieldId:
if (field.Type == TType.String)
{
message = await inputProtocol.ReadStringAsync(cancellationToken);
}
else
{
await TProtocolUtil.SkipAsync(inputProtocol, field.Type, cancellationToken);
}
break;
case ExTypeFieldId:
if (field.Type == TType.I32)
{
type = (ExceptionType) await inputProtocol.ReadI32Async(cancellationToken);
}
else
{
await TProtocolUtil.SkipAsync(inputProtocol, field.Type, cancellationToken);
}
break;
default:
await TProtocolUtil.SkipAsync(inputProtocol, field.Type, cancellationToken);
break;
}
await inputProtocol.ReadFieldEndAsync(cancellationToken);
}
await inputProtocol.ReadStructEndAsync(cancellationToken);
return new TApplicationException(type, message);
}
public async Task WriteAsync(TProtocol outputProtocol, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
const string messageTypeFieldName = "message";
const string exTypeFieldName = "exType";
const string structApplicationExceptionName = "TApplicationException";
var struc = new TStruct(structApplicationExceptionName);
var field = new TField();
await outputProtocol.WriteStructBeginAsync(struc, cancellationToken);
if (!string.IsNullOrEmpty(Message))
{
field.Name = messageTypeFieldName;
field.Type = TType.String;
field.ID = MessageTypeFieldId;
await outputProtocol.WriteFieldBeginAsync(field, cancellationToken);
await outputProtocol.WriteStringAsync(Message, cancellationToken);
await outputProtocol.WriteFieldEndAsync(cancellationToken);
}
field.Name = exTypeFieldName;
field.Type = TType.I32;
field.ID = ExTypeFieldId;
await outputProtocol.WriteFieldBeginAsync(field, cancellationToken);
await outputProtocol.WriteI32Async((int) Type, cancellationToken);
await outputProtocol.WriteFieldEndAsync(cancellationToken);
await outputProtocol.WriteFieldStopAsync(cancellationToken);
await outputProtocol.WriteStructEndAsync(cancellationToken);
}
}
}