blob: 53bf862ea5bc8b2b69b00fa91e08aae4c33b4048 [file] [log] [blame]
Rohan Agrawalc32d9932020-06-15 11:01:47 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20package thrift
21
22import (
23 "errors"
24)
25
26// Generic Thrift exception
27type TException interface {
28 error
David K. Bainbridgee05cf0c2021-08-19 03:16:50 +000029
30 TExceptionType() TExceptionType
Rohan Agrawalc32d9932020-06-15 11:01:47 +000031}
32
33// Prepends additional information to an error without losing the Thrift exception interface
34func PrependError(prepend string, err error) error {
David K. Bainbridgee05cf0c2021-08-19 03:16:50 +000035 msg := prepend + err.Error()
36
37 var te TException
38 if errors.As(err, &te) {
39 switch te.TExceptionType() {
40 case TExceptionTypeTransport:
41 if t, ok := err.(TTransportException); ok {
42 return prependTTransportException(prepend, t)
43 }
44 case TExceptionTypeProtocol:
45 if t, ok := err.(TProtocolException); ok {
46 return prependTProtocolException(prepend, t)
47 }
48 case TExceptionTypeApplication:
49 var t TApplicationException
50 if errors.As(err, &t) {
51 return NewTApplicationException(t.TypeId(), msg)
52 }
53 }
54
55 return wrappedTException{
56 err: err,
57 msg: msg,
58 tExceptionType: te.TExceptionType(),
59 }
Rohan Agrawalc32d9932020-06-15 11:01:47 +000060 }
61
David K. Bainbridgee05cf0c2021-08-19 03:16:50 +000062 return errors.New(msg)
Rohan Agrawalc32d9932020-06-15 11:01:47 +000063}
David K. Bainbridgee05cf0c2021-08-19 03:16:50 +000064
65// TExceptionType is an enum type to categorize different "subclasses" of TExceptions.
66type TExceptionType byte
67
68// TExceptionType values
69const (
70 TExceptionTypeUnknown TExceptionType = iota
71 TExceptionTypeCompiled // TExceptions defined in thrift files and generated by thrift compiler
72 TExceptionTypeApplication // TApplicationExceptions
73 TExceptionTypeProtocol // TProtocolExceptions
74 TExceptionTypeTransport // TTransportExceptions
75)
76
77// WrapTException wraps an error into TException.
78//
79// If err is nil or already TException, it's returned as-is.
80// Otherwise it will be wraped into TException with TExceptionType() returning
81// TExceptionTypeUnknown, and Unwrap() returning the original error.
82func WrapTException(err error) TException {
83 if err == nil {
84 return nil
85 }
86
87 if te, ok := err.(TException); ok {
88 return te
89 }
90
91 return wrappedTException{
92 err: err,
93 msg: err.Error(),
94 tExceptionType: TExceptionTypeUnknown,
95 }
96}
97
98type wrappedTException struct {
99 err error
100 msg string
101 tExceptionType TExceptionType
102}
103
104func (w wrappedTException) Error() string {
105 return w.msg
106}
107
108func (w wrappedTException) TExceptionType() TExceptionType {
109 return w.tExceptionType
110}
111
112func (w wrappedTException) Unwrap() error {
113 return w.err
114}
115
116var _ TException = wrappedTException{}