|  | // 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); | 
|  | } | 
|  | } | 
|  | } |