exception.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /*
  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. package thrift
  20. import (
  21. "errors"
  22. )
  23. // Generic Thrift exception
  24. type TException interface {
  25. error
  26. TExceptionType() TExceptionType
  27. }
  28. // Prepends additional information to an error without losing the Thrift exception interface
  29. func PrependError(prepend string, err error) error {
  30. msg := prepend + err.Error()
  31. var te TException
  32. if errors.As(err, &te) {
  33. switch te.TExceptionType() {
  34. case TExceptionTypeTransport:
  35. if t, ok := err.(TTransportException); ok {
  36. return prependTTransportException(prepend, t)
  37. }
  38. case TExceptionTypeProtocol:
  39. if t, ok := err.(TProtocolException); ok {
  40. return prependTProtocolException(prepend, t)
  41. }
  42. case TExceptionTypeApplication:
  43. var t TApplicationException
  44. if errors.As(err, &t) {
  45. return NewTApplicationException(t.TypeId(), msg)
  46. }
  47. }
  48. return wrappedTException{
  49. err: err,
  50. msg: msg,
  51. tExceptionType: te.TExceptionType(),
  52. }
  53. }
  54. return errors.New(msg)
  55. }
  56. // TExceptionType is an enum type to categorize different "subclasses" of TExceptions.
  57. type TExceptionType byte
  58. // TExceptionType values
  59. const (
  60. TExceptionTypeUnknown TExceptionType = iota
  61. TExceptionTypeCompiled // TExceptions defined in thrift files and generated by thrift compiler
  62. TExceptionTypeApplication // TApplicationExceptions
  63. TExceptionTypeProtocol // TProtocolExceptions
  64. TExceptionTypeTransport // TTransportExceptions
  65. )
  66. // WrapTException wraps an error into TException.
  67. //
  68. // If err is nil or already TException, it's returned as-is.
  69. // Otherwise it will be wraped into TException with TExceptionType() returning
  70. // TExceptionTypeUnknown, and Unwrap() returning the original error.
  71. func WrapTException(err error) TException {
  72. if err == nil {
  73. return nil
  74. }
  75. if te, ok := err.(TException); ok {
  76. return te
  77. }
  78. return wrappedTException{
  79. err: err,
  80. msg: err.Error(),
  81. tExceptionType: TExceptionTypeUnknown,
  82. }
  83. }
  84. type wrappedTException struct {
  85. err error
  86. msg string
  87. tExceptionType TExceptionType
  88. }
  89. func (w wrappedTException) Error() string {
  90. return w.msg
  91. }
  92. func (w wrappedTException) TExceptionType() TExceptionType {
  93. return w.tExceptionType
  94. }
  95. func (w wrappedTException) Unwrap() error {
  96. return w.err
  97. }
  98. var _ TException = wrappedTException{}