1
0

exception.cc 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /**
  2. * Copyright 2005 The Apache Software Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "exception.hh"
  17. #include <execinfo.h>
  18. #include <errno.h>
  19. #include <sstream>
  20. #include <typeinfo>
  21. using std::string;
  22. namespace hadoop {
  23. /**
  24. * Create an exception.
  25. * @param message The message to give to the user.
  26. * @param reason The exception that caused the new exception.
  27. */
  28. Exception::Exception(const string& message,
  29. const string& component,
  30. const string& location,
  31. const Exception* reason
  32. ): mMessage(message),
  33. mComponent(component),
  34. mLocation(location),
  35. mReason(reason)
  36. {
  37. mCalls = backtrace(mCallStack, sMaxCallStackDepth);
  38. }
  39. /**
  40. * Copy the exception.
  41. * Clones the reason, if there is one.
  42. */
  43. Exception::Exception(const Exception& other
  44. ): mMessage(other.mMessage),
  45. mComponent(other.mComponent),
  46. mLocation(other.mLocation),
  47. mCalls(other.mCalls)
  48. {
  49. for(int i=0; i < mCalls; ++i) {
  50. mCallStack[i] = other.mCallStack[i];
  51. }
  52. if (other.mReason) {
  53. mReason = other.mReason->clone();
  54. } else {
  55. mReason = NULL;
  56. }
  57. }
  58. Exception::~Exception() throw () {
  59. delete mReason;
  60. }
  61. /**
  62. * Print all of the information about the exception.
  63. */
  64. void Exception::print(std::ostream& stream) const {
  65. stream << "Exception " << getTypename();
  66. if (mComponent.size() != 0) {
  67. stream << " (" << mComponent << ")";
  68. }
  69. stream << ": " << mMessage << "\n";
  70. if (mLocation.size() != 0) {
  71. stream << " thrown at " << mLocation << "\n";
  72. }
  73. printCallStack(stream);
  74. if (mReason) {
  75. stream << "caused by: ";
  76. mReason->print(stream);
  77. }
  78. stream.flush();
  79. }
  80. /**
  81. * Result of print() as a string.
  82. */
  83. string Exception::toString() const {
  84. std::ostringstream stream;
  85. print(stream);
  86. return stream.str();
  87. }
  88. /**
  89. * Print the call stack where the exception was created.
  90. */
  91. void Exception::printCallStack(std::ostream& stream) const {
  92. char ** symbols = backtrace_symbols(mCallStack, mCalls);
  93. for(int i=0; i < mCalls; ++i) {
  94. stream << " ";
  95. if (i == 0) {
  96. stream << "at ";
  97. } else {
  98. stream << "from ";
  99. }
  100. stream << symbols[i] << "\n";
  101. }
  102. free(symbols);
  103. }
  104. const char* Exception::getTypename() const {
  105. return "Exception";
  106. }
  107. Exception* Exception::clone() const {
  108. return new Exception(*this);
  109. }
  110. IOException::IOException(const string& message,
  111. const string& component,
  112. const string& location,
  113. const Exception* reason
  114. ): Exception(message, component, location, reason)
  115. {
  116. }
  117. const char* IOException::getTypename() const {
  118. return "IOException";
  119. }
  120. IOException* IOException::clone() const {
  121. return new IOException(*this);
  122. }
  123. }