blob: 514db9a086be0bae5ab7f08cf7f9f005c33e839a [file] [log] [blame]
Jens Geyerdce22992020-05-16 23:02:27 +02001// Licensed to the Apache Software Foundation(ASF) under one
Jens Geyeraa0c8b32019-01-28 23:27:45 +01002// or more contributor license agreements.See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License. You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied. See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18using System.Threading;
19using System.Threading.Tasks;
20using Thrift.Protocol;
21using Thrift.Protocol.Entities;
22using Thrift.Protocol.Utilities;
23
24namespace Thrift
25{
26 // ReSharper disable once InconsistentNaming
27 public class TApplicationException : TException
28 {
29 public enum ExceptionType
30 {
31 Unknown,
32 UnknownMethod,
33 InvalidMessageType,
34 WrongMethodName,
35 BadSequenceId,
36 MissingResult,
37 InternalError,
38 ProtocolError,
39 InvalidTransform,
40 InvalidProtocol,
41 UnsupportedClientType
42 }
43
44 private const int MessageTypeFieldId = 1;
45 private const int ExTypeFieldId = 2;
46
Jens Geyeradde44b2019-02-05 01:00:02 +010047 public ExceptionType Type { get; private set; }
Jens Geyeraa0c8b32019-01-28 23:27:45 +010048
49 public TApplicationException()
50 {
51 }
52
53 public TApplicationException(ExceptionType type)
54 {
55 Type = type;
56 }
57
58 public TApplicationException(ExceptionType type, string message)
59 : base(message, null) // TApplicationException is serializable, but we never serialize InnerException
60 {
61 Type = type;
62 }
63
Jens Geyer5a17b132019-05-26 15:53:37 +020064 public static async ValueTask<TApplicationException> ReadAsync(TProtocol inputProtocol, CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +010065 {
66 string message = null;
67 var type = ExceptionType.Unknown;
68
69 await inputProtocol.ReadStructBeginAsync(cancellationToken);
70 while (true)
71 {
72 var field = await inputProtocol.ReadFieldBeginAsync(cancellationToken);
73 if (field.Type == TType.Stop)
74 {
75 break;
76 }
77
78 switch (field.ID)
79 {
80 case MessageTypeFieldId:
81 if (field.Type == TType.String)
82 {
83 message = await inputProtocol.ReadStringAsync(cancellationToken);
84 }
85 else
86 {
87 await TProtocolUtil.SkipAsync(inputProtocol, field.Type, cancellationToken);
88 }
89 break;
90 case ExTypeFieldId:
91 if (field.Type == TType.I32)
92 {
93 type = (ExceptionType) await inputProtocol.ReadI32Async(cancellationToken);
94 }
95 else
96 {
97 await TProtocolUtil.SkipAsync(inputProtocol, field.Type, cancellationToken);
98 }
99 break;
100 default:
101 await TProtocolUtil.SkipAsync(inputProtocol, field.Type, cancellationToken);
102 break;
103 }
104
105 await inputProtocol.ReadFieldEndAsync(cancellationToken);
106 }
107
108 await inputProtocol.ReadStructEndAsync(cancellationToken);
109
110 return new TApplicationException(type, message);
111 }
112
113 public async Task WriteAsync(TProtocol outputProtocol, CancellationToken cancellationToken)
114 {
Jens Geyerdce22992020-05-16 23:02:27 +0200115 cancellationToken.ThrowIfCancellationRequested();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100116
117 const string messageTypeFieldName = "message";
118 const string exTypeFieldName = "exType";
119 const string structApplicationExceptionName = "TApplicationException";
120
121 var struc = new TStruct(structApplicationExceptionName);
122 var field = new TField();
123
124 await outputProtocol.WriteStructBeginAsync(struc, cancellationToken);
125
126 if (!string.IsNullOrEmpty(Message))
127 {
128 field.Name = messageTypeFieldName;
129 field.Type = TType.String;
130 field.ID = MessageTypeFieldId;
131 await outputProtocol.WriteFieldBeginAsync(field, cancellationToken);
132 await outputProtocol.WriteStringAsync(Message, cancellationToken);
133 await outputProtocol.WriteFieldEndAsync(cancellationToken);
134 }
135
136 field.Name = exTypeFieldName;
137 field.Type = TType.I32;
138 field.ID = ExTypeFieldId;
139
140 await outputProtocol.WriteFieldBeginAsync(field, cancellationToken);
141 await outputProtocol.WriteI32Async((int) Type, cancellationToken);
142 await outputProtocol.WriteFieldEndAsync(cancellationToken);
143 await outputProtocol.WriteFieldStopAsync(cancellationToken);
144 await outputProtocol.WriteStructEndAsync(cancellationToken);
145 }
146 }
Jens Geyerdce22992020-05-16 23:02:27 +0200147}