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