github.com/searKing/golang/go@v1.2.74/error/exception/throwable.go (about)

     1  // Copyright 2020 The searKing Author. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package exception
     6  
     7  import (
     8  	"bytes"
     9  	"fmt"
    10  	"io"
    11  	"os"
    12  	"reflect"
    13  	"runtime/debug"
    14  
    15  	"github.com/searKing/golang/go/util/object"
    16  )
    17  
    18  const (
    19  	/** Message for trying to suppress a null exception. */
    20  	NullCauseMessage string = "Cannot suppress a null exception."
    21  	/** Message for trying to suppress oneself. */
    22  	SelfSuppressionMessage string = "Self-suppression not permitted"
    23  	/** Caption  for labeling causative exception stack traces */
    24  	CauseCaption string = "Caused by: "
    25  	/** Caption for labeling suppressed exception stack traces */
    26  	SuppressedCaption string = "Suppressed: "
    27  )
    28  
    29  var (
    30  	/**
    31  	 * A shared value for an empty stack.
    32  	 */
    33  	UnassignedStack = make([]byte, 0)
    34  	// Setting this static field introduces an acceptable
    35  	// initialization dependency on a few java.util classes.
    36  	SuppressedSentinel = make([]Throwable, 0)
    37  
    38  	EmptyThrowableArray = make([]Throwable, 0)
    39  )
    40  
    41  type Throwable interface {
    42  	GetMessage() string
    43  	GetLocalizedMessage() string
    44  	GetCause() Throwable
    45  	InitCause(cause Throwable) Throwable
    46  	String() string
    47  	PrintStackTrace()
    48  	PrintStackTrace1(writer io.Writer)
    49  	PrintEnclosedStackTrace(writer io.Writer, enclosingTrace []byte,
    50  		caption string, prefix string, dejaVu map[Throwable]struct{})
    51  	fillInStackTrack() Throwable
    52  	GetSuppressed() []Throwable
    53  	GetStackTrace() []byte
    54  	Error() string
    55  }
    56  
    57  /**
    58   * The {@code Throwable} class is the superclass of all errors and
    59   * exceptions in the Java language. Only objects that are instances of this
    60   * class (or one of its subclasses) are thrown by the Java Virtual Machine or
    61   * can be thrown by the Java {@code throw} statement. Similarly, only
    62   * this class or one of its subclasses can be the argument type in a
    63   * {@code catch} clause.
    64   *
    65   * For the purposes of compile-time checking of exceptions, {@code
    66   * Throwable} and any subclass of {@code Throwable} that is not also a
    67   * subclass of either {@link RuntimeException} or {@link Error} are
    68   * regarded as checked exceptions.
    69   *
    70   * <p>Instances of two subclasses, {@link java.lang.Error} and
    71   * {@link java.lang.Exception}, are conventionally used to indicate
    72   * that exceptional situations have occurred. Typically, these instances
    73   * are freshly created in the context of the exceptional situation so
    74   * as to include relevant information (such as stack trace data).
    75   *
    76   * <p>A throwable contains a snapshot of the execution stack of its
    77   * thread at the time it was created. It can also contain a message
    78   * string that gives more information about the error. Over time, a
    79   * throwable can {@linkplain Throwable#addSuppressed suppress} other
    80   * throwables from being propagated.  Finally, the throwable can also
    81   * contain a <i>cause</i>: another throwable that caused this
    82   * throwable to be constructed.  The recording of this causal information
    83   * is referred to as the <i>chained exception</i> facility, as the
    84   * cause can, itself, have a cause, and so on, leading to a "chain" of
    85   * exceptions, each caused by another.
    86   *
    87   * <p>One reason that a throwable may have a cause is that the class that
    88   * throws it is built atop a lower layered abstraction, and an operation on
    89   * the upper layer fails due to a failure in the lower layer.  It would be bad
    90   * design to let the throwable thrown by the lower layer propagate outward, as
    91   * it is generally unrelated to the abstraction provided by the upper layer.
    92   * Further, doing so would tie the API of the upper layer to the details of
    93   * its implementation, assuming the lower layer's exception was a checked
    94   * exception.  Throwing a "wrapped exception" (i.e., an exception containing a
    95   * cause) allows the upper layer to communicate the details of the failure to
    96   * its caller without incurring either of these shortcomings.  It preserves
    97   * the flexibility to change the implementation of the upper layer without
    98   * changing its API (in particular, the set of exceptions thrown by its
    99   * methods).
   100   *
   101   * <p>A second reason that a throwable may have a cause is that the method
   102   * that throws it must conform to a general-purpose interface that does not
   103   * permit the method to throw the cause directly.  For example, suppose
   104   * a persistent collection conforms to the {@link java.util.Collection
   105   * Collection} interface, and that its persistence is implemented atop
   106   * {@code java.io}.  Suppose the internals of the {@code add} method
   107   * can throw an {@link java.io.IOException IOException}.  The implementation
   108   * can communicate the details of the {@code IOException} to its caller
   109   * while conforming to the {@code Collection} interface by wrapping the
   110   * {@code IOException} in an appropriate unchecked exception.  (The
   111   * specification for the persistent collection should indicate that it is
   112   * capable of throwing such exceptions.)
   113   *
   114   * <p>A cause can be associated with a throwable in two ways: via a
   115   * constructor that takes the cause as an argument, or via the
   116   * {@link #initCause(Throwable)} method.  New throwable classes that
   117   * wish to allow causes to be associated with them should provide constructors
   118   * that take a cause and delegate (perhaps indirectly) to one of the
   119   * {@code Throwable} constructors that takes a cause.
   120   *
   121   * Because the {@code initCause} method is public, it allows a cause to be
   122   * associated with any throwable, even a "legacy throwable" whose
   123   * implementation predates the addition of the exception chaining mechanism to
   124   * {@code Throwable}.
   125   *
   126   * <p>By convention, class {@code Throwable} and its subclasses have two
   127   * constructors, one that takes no arguments and one that takes a
   128   * {@code String} argument that can be used to produce a detail message.
   129   * Further, those subclasses that might likely have a cause associated with
   130   * them should have two more constructors, one that takes a
   131   * {@code Throwable} (the cause), and one that takes a
   132   * {@code String} (the detail message) and a {@code Throwable} (the
   133   * cause).
   134   *
   135   * @author  unascribed
   136   * @author  Josh Bloch (Added exception chaining and programmatic access to
   137   *          stack trace in 1.4.)
   138   * @jls 11.2 Compile-Time Checking of Exceptions
   139   * @since 1.0
   140   */
   141  type ThrowableObject struct {
   142  	/**
   143  	 * Specific details about the Throwable.  For example, for
   144  	 * {@code FileNotFoundException}, this contains the name of
   145  	 * the file that could not be found.
   146  	 *
   147  	 * @serial
   148  	 */
   149  	detailMessage string
   150  
   151  	/**
   152  	 * The throwable that caused this throwable to get thrown, or null if this
   153  	 * throwable was not caused by another throwable, or if the causative
   154  	 * throwable is unknown.  If this field is equal to this throwable itself,
   155  	 * it indicates that the cause of this throwable has not yet been
   156  	 * initialized.
   157  	 *
   158  	 * @serial
   159  	 * @since 1.4
   160  	 */
   161  	cause Throwable
   162  
   163  	/**
   164  	 * The stack trace, as returned by {@link #getStackTrace()}.
   165  	 *
   166  	 * The field is initialized to a zero-length array.  A {@code
   167  	 * null} value of this field indicates subsequent calls to {@link
   168  	 * #setStackTrace(StackTraceElement[])} and {@link
   169  	 * #fillInStackTrace()} will be no-ops.
   170  	 *
   171  	 * @serial
   172  	 * @since 1.4
   173  	 */
   174  	stackTrace []byte
   175  
   176  	/**
   177  	 * The list of suppressed exceptions, as returned by {@link
   178  	 * #getSuppressed()}.  The list is initialized to a zero-element
   179  	 * unmodifiable sentinel list.  When a serialized Throwable is
   180  	 * read in, if the {@code suppressedExceptions} field points to a
   181  	 * zero-element list, the field is reset to the sentinel value.
   182  	 *
   183  	 * @serial
   184  	 * @since 1.7
   185  	 */
   186  	suppressedExceptions []Throwable
   187  }
   188  
   189  /**
   190   * Constructs a new throwable with {@code null} as its detail message.
   191   * The cause is not initialized, and may subsequently be initialized by a
   192   * call to {@link #initCause}.
   193   *
   194   * <p>The {@link #fillInStackTrace()} method is called to initialize
   195   * the stack trace data in the newly created throwable.
   196   */
   197  func NewThrowable() *ThrowableObject {
   198  	return NewThrowable1("")
   199  }
   200  
   201  /**
   202   * Constructs a new throwable with the specified detail message.  The
   203   * cause is not initialized, and may subsequently be initialized by
   204   * a call to {@link #initCause}.
   205   *
   206   * <p>The {@link #fillInStackTrace()} method is called to initialize
   207   * the stack trace data in the newly created throwable.
   208   *
   209   * @param   message   the detail message. The detail message is saved for
   210   *          later retrieval by the {@link #getMessage()} method.
   211   */
   212  func NewThrowable1(message string) *ThrowableObject {
   213  	t := NewThrowable2(message, nil)
   214  	t.cause = t
   215  	return t
   216  }
   217  
   218  /**
   219   * Constructs a new throwable with the specified detail message and
   220   * cause.  <p>Note that the detail message associated with
   221   * {@code cause} is <i>not</i> automatically incorporated in
   222   * this throwable's detail message.
   223   *
   224   * <p>The {@link #fillInStackTrace()} method is called to initialize
   225   * the stack trace data in the newly created throwable.
   226   *
   227   * @param  message the detail message (which is saved for later retrieval
   228   *         by the {@link #getMessage()} method).
   229   * @param  cause the cause (which is saved for later retrieval by the
   230   *         {@link #getCause()} method).  (A {@code null} value is
   231   *         permitted, and indicates that the cause is nonexistent or
   232   *         unknown.)
   233   * @since  1.4
   234   */
   235  func NewThrowable2(message string, cause Throwable) *ThrowableObject {
   236  	return NewThrowable4(message, cause, true, true)
   237  }
   238  
   239  /**
   240   * Constructs a new throwable with the specified detail message,
   241   * cause, {@linkplain #addSuppressed suppression} enabled or
   242   * disabled, and writable stack trace enabled or disabled.  If
   243   * suppression is disabled, {@link #getSuppressed} for this object
   244   * will return a zero-length array and calls to {@link
   245   * #addSuppressed} that would otherwise append an exception to the
   246   * suppressed list will have no effect.  If the writable stack
   247   * trace is false, this constructor will not call {@link
   248   * #fillInStackTrace()}, a {@code null} will be written to the
   249   * {@code stackTrace} field, and subsequent calls to {@code
   250   * fillInStackTrace} and {@link
   251   * #setStackTrace(StackTraceElement[])} will not set the stack
   252   * trace.  If the writable stack trace is false, {@link
   253   * #getStackTrace} will return a zero length array.
   254   *
   255   * <p>Note that the other constructors of {@code Throwable} treat
   256   * suppression as being enabled and the stack trace as being
   257   * writable.  Subclasses of {@code Throwable} should document any
   258   * conditions under which suppression is disabled and document
   259   * conditions under which the stack trace is not writable.
   260   * Disabling of suppression should only occur in exceptional
   261   * circumstances where special requirements exist, such as a
   262   * virtual machine reusing exception objects under low-memory
   263   * situations.  Circumstances where a given exception object is
   264   * repeatedly caught and rethrown, such as to implement control
   265   * flow between two sub-systems, is another situation where
   266   * immutable throwable objects would be appropriate.
   267   *
   268   * @param  message the detail message.
   269   * @param cause the cause.  (A {@code null} value is permitted,
   270   * and indicates that the cause is nonexistent or unknown.)
   271   * @param enableSuppression whether or not suppression is enabled or disabled
   272   * @param writableStackTrace whether or not the stack trace should be
   273   *                           writable
   274   *
   275   * @see OutOfMemoryError
   276   * @see NullPointerException
   277   * @see ArithmeticException
   278   * @since 1.7
   279   */
   280  func NewThrowable4(message string, cause Throwable, enableSuppression, writableStackTrace bool) *ThrowableObject {
   281  	t := &ThrowableObject{}
   282  	t.init()
   283  	if writableStackTrace {
   284  		t.fillInStackTrack()
   285  	} else {
   286  		t.stackTrace = nil
   287  	}
   288  	t.detailMessage = message
   289  	t.cause = cause
   290  	if !enableSuppression {
   291  		t.suppressedExceptions = nil
   292  	}
   293  	return t
   294  }
   295  
   296  // member variable init as C++
   297  func (t *ThrowableObject) init() {
   298  	t.cause = t
   299  	t.stackTrace = UnassignedStack
   300  	t.suppressedExceptions = SuppressedSentinel
   301  }
   302  
   303  func (t *ThrowableObject) Error() string {
   304  	return t.GetMessage()
   305  }
   306  
   307  /**
   308   * Returns the detail message string of this throwable.
   309   *
   310   * @return  the detail message string of this {@code Throwable} instance
   311   *          (which may be {@code null}).
   312   */
   313  func (t *ThrowableObject) GetMessage() string {
   314  	return t.detailMessage
   315  }
   316  
   317  /**
   318   * Creates a localized description of this throwable.
   319   * Subclasses may override this method in order to produce a
   320   * locale-specific message.  For subclasses that do not override this
   321   * method, the default implementation returns the same result as
   322   * {@code getMessage()}.
   323   *
   324   * @return  The localized description of this throwable.
   325   * @since   1.1
   326   */
   327  func (t *ThrowableObject) GetLocalizedMessage() string {
   328  	return t.GetMessage()
   329  }
   330  
   331  /**
   332   * Returns the cause of this throwable or {@code null} if the
   333   * cause is nonexistent or unknown.  (The cause is the throwable that
   334   * caused this throwable to get thrown.)
   335   *
   336   * <p>This implementation returns the cause that was supplied via one of
   337   * the constructors requiring a {@code Throwable}, or that was set after
   338   * creation with the {@link #initCause(Throwable)} method.  While it is
   339   * typically unnecessary to override this method, a subclass can override
   340   * it to return a cause set by some other means.  This is appropriate for
   341   * a "legacy chained throwable" that predates the addition of chained
   342   * exceptions to {@code Throwable}.  Note that it is <i>not</i>
   343   * necessary to override any of the {@code PrintStackTrace} methods,
   344   * all of which invoke the {@code getCause} method to determine the
   345   * cause of a throwable.
   346   *
   347   * @return  the cause of this throwable or {@code null} if the
   348   *          cause is nonexistent or unknown.
   349   * @since 1.4
   350   */
   351  func (t *ThrowableObject) GetCause() Throwable {
   352  	if t.cause == t {
   353  		return nil
   354  	}
   355  	return t.cause
   356  }
   357  
   358  /**
   359   * Initializes the <i>cause</i> of this throwable to the specified value.
   360   * (The cause is the throwable that caused this throwable to get thrown.)
   361   *
   362   * <p>This method can be called at most once.  It is generally called from
   363   * within the constructor, or immediately after creating the
   364   * throwable.  If this throwable was created
   365   * with {@link #Throwable(Throwable)} or
   366   * {@link #Throwable(String,Throwable)}, this method cannot be called
   367   * even once.
   368   *
   369   * <p>An example of using this method on a legacy throwable type
   370   * without other support for setting the cause is:
   371   *
   372   * <pre>
   373   * try {
   374   *     lowLevelOp();
   375   * } catch (LowLevelException le) {
   376   *     throw (HighLevelException)
   377   *           new HighLevelException().initCause(le); // Legacy constructor
   378   * }
   379   * </pre>
   380   *
   381   * @param  cause the cause (which is saved for later retrieval by the
   382   *         {@link #getCause()} method).  (A {@code null} value is
   383   *         permitted, and indicates that the cause is nonexistent or
   384   *         unknown.)
   385   * @return  a reference to this {@code Throwable} instance.
   386   * @throws IllegalArgumentException if {@code cause} is this
   387   *         throwable.  (A throwable cannot be its own cause.)
   388   * @throws IllegalStateException if this throwable was
   389   *         created with {@link #Throwable(Throwable)} or
   390   *         {@link #Throwable(String,Throwable)}, or this method has already
   391   *         been called on this throwable.
   392   * @since  1.4
   393   */
   394  func (t *ThrowableObject) InitCause(cause Throwable) Throwable {
   395  	if t.cause != t {
   396  		return NewIllegalStateException2("Can't overwrite cause with "+object.ToString(cause, "a nil"), t)
   397  	}
   398  	if cause == t {
   399  		return NewIllegalArgumentException2("Self-causation not permitted", t)
   400  	}
   401  	t.cause = cause
   402  	return t
   403  }
   404  
   405  /**
   406   * Returns a short description of this throwable.
   407   * The result is the concatenation of:
   408   * <ul>
   409   * <li> the {@linkplain Class#getName() name} of the class of this object
   410   * <li> ": " (a colon and a space)
   411   * <li> the result of invoking this object's {@link #getLocalizedMessage}
   412   *      method
   413   * </ul>
   414   * If {@code getLocalizedMessage} returns {@code null}, then just
   415   * the class name is returned.
   416   *
   417   * @return a string representation of this throwable.
   418   */
   419  func (t *ThrowableObject) String() string {
   420  	s := object.GetFunc().Name()
   421  	message := t.GetLocalizedMessage()
   422  	if len(message) != 0 {
   423  		return s + ":" + message
   424  	}
   425  	return s
   426  }
   427  
   428  /**
   429   * Prints this throwable and its backtrace to the
   430   * standard error stream. This method prints a stack trace for this
   431   * {@code Throwable} object on the error output stream that is
   432   * the value of the field {@code System.err}. The first line of
   433   * output contains the result of the {@link #toString()} method for
   434   * this object.  Remaining lines represent data previously recorded by
   435   * the method {@link #fillInStackTrace()}. The format of this
   436   * information depends on the implementation, but the following
   437   * example may be regarded as typical:
   438   * <blockquote><pre>
   439   * java.lang.NullPointerException
   440   *         at MyClass.mash(MyClass.java:9)
   441   *         at MyClass.crunch(MyClass.java:6)
   442   *         at MyClass.main(MyClass.java:3)
   443   * </pre></blockquote>
   444   * This example was produced by running the program:
   445   * <pre>
   446   * class MyClass {
   447   *     public static void main(String[] args) {
   448   *         crunch(null);
   449   *     }
   450   *     static void crunch(int[] a) {
   451   *         mash(a);
   452   *     }
   453   *     static void mash(int[] b) {
   454   *         System.out.println(b[0]);
   455   *     }
   456   * }
   457   * </pre>
   458   * The backtrace for a throwable with an initialized, non-null cause
   459   * should generally include the backtrace for the cause.  The format
   460   * of this information depends on the implementation, but the following
   461   * example may be regarded as typical:
   462   * <pre>
   463   * HighLevelException: MidLevelException: LowLevelException
   464   *         at Junk.a(Junk.java:13)
   465   *         at Junk.main(Junk.java:4)
   466   * Caused by: MidLevelException: LowLevelException
   467   *         at Junk.c(Junk.java:23)
   468   *         at Junk.b(Junk.java:17)
   469   *         at Junk.a(Junk.java:11)
   470   *         ... 1 more
   471   * Caused by: LowLevelException
   472   *         at Junk.e(Junk.java:30)
   473   *         at Junk.d(Junk.java:27)
   474   *         at Junk.c(Junk.java:21)
   475   *         ... 3 more
   476   * </pre>
   477   * Note the presence of lines containing the characters {@code "..."}.
   478   * These lines indicate that the remainder of the stack trace for this
   479   * exception matches the indicated number of frames from the bottom of the
   480   * stack trace of the exception that was caused by this exception (the
   481   * "enclosing" exception).  This shorthand can greatly reduce the length
   482   * of the output in the common case where a wrapped exception is thrown
   483   * from same method as the "causative exception" is caught.  The above
   484   * example was produced by running the program:
   485   * <pre>
   486   * public class Junk {
   487   *     public static void main(String args[]) {
   488   *         try {
   489   *             a();
   490   *         } catch(HighLevelException e) {
   491   *             e.printStackTrace();
   492   *         }
   493   *     }
   494   *     static void a() throws HighLevelException {
   495   *         try {
   496   *             b();
   497   *         } catch(MidLevelException e) {
   498   *             throw new HighLevelException(e);
   499   *         }
   500   *     }
   501   *     static void b() throws MidLevelException {
   502   *         c();
   503   *     }
   504   *     static void c() throws MidLevelException {
   505   *         try {
   506   *             d();
   507   *         } catch(LowLevelException e) {
   508   *             throw new MidLevelException(e);
   509   *         }
   510   *     }
   511   *     static void d() throws LowLevelException {
   512   *        e();
   513   *     }
   514   *     static void e() throws LowLevelException {
   515   *         throw new LowLevelException();
   516   *     }
   517   * }
   518   *
   519   * class HighLevelException extends Exception {
   520   *     HighLevelException(Throwable cause) { super(cause); }
   521   * }
   522   *
   523   * class MidLevelException extends Exception {
   524   *     MidLevelException(Throwable cause)  { super(cause); }
   525   * }
   526   *
   527   * class LowLevelException extends Exception {
   528   * }
   529   * </pre>
   530   * As of release 7, the platform supports the notion of
   531   * <i>suppressed exceptions</i> (in conjunction with the {@code
   532   * try}-with-resources statement). Any exceptions that were
   533   * suppressed in order to deliver an exception are printed out
   534   * beneath the stack trace.  The format of this information
   535   * depends on the implementation, but the following example may be
   536   * regarded as typical:
   537   *
   538   * <pre>
   539   * Exception in thread "main" java.lang.Exception: Something happened
   540   *  at Foo.bar(Foo.java:10)
   541   *  at Foo.main(Foo.java:5)
   542   *  Suppressed: Resource$CloseFailException: Resource ID = 0
   543   *          at Resource.close(Resource.java:26)
   544   *          at Foo.bar(Foo.java:9)
   545   *          ... 1 more
   546   * </pre>
   547   * Note that the "... n more" notation is used on suppressed exceptions
   548   * just at it is used on causes. Unlike causes, suppressed exceptions are
   549   * indented beyond their "containing exceptions."
   550   *
   551   * <p>An exception can have both a cause and one or more suppressed
   552   * exceptions:
   553   * <pre>
   554   * Exception in thread "main" java.lang.Exception: Main block
   555   *  at Foo3.main(Foo3.java:7)
   556   *  Suppressed: Resource$CloseFailException: Resource ID = 2
   557   *          at Resource.close(Resource.java:26)
   558   *          at Foo3.main(Foo3.java:5)
   559   *  Suppressed: Resource$CloseFailException: Resource ID = 1
   560   *          at Resource.close(Resource.java:26)
   561   *          at Foo3.main(Foo3.java:5)
   562   * Caused by: java.lang.Exception: I did it
   563   *  at Foo3.main(Foo3.java:8)
   564   * </pre>
   565   * Likewise, a suppressed exception can have a cause:
   566   * <pre>
   567   * Exception in thread "main" java.lang.Exception: Main block
   568   *  at Foo4.main(Foo4.java:6)
   569   *  Suppressed: Resource2$CloseFailException: Resource ID = 1
   570   *          at Resource2.close(Resource2.java:20)
   571   *          at Foo4.main(Foo4.java:5)
   572   *  Caused by: java.lang.Exception: Rats, you caught me
   573   *          at Resource2$CloseFailException.&lt;init&gt;(Resource2.java:45)
   574   *          ... 2 more
   575   * </pre>
   576   */
   577  func (t *ThrowableObject) PrintStackTrace() {
   578  	t.PrintStackTrace1(os.Stderr)
   579  }
   580  
   581  /**
   582   * Prints this throwable and its backtrace to the specified print stream.
   583   *
   584   * @param s {@code PrintStream} to use for output
   585   */
   586  func (t *ThrowableObject) PrintStackTrace1(writer io.Writer) {
   587  	// Guard against malicious overrides of Throwable.equals by
   588  	// using a Set with identity equality semantics.
   589  	var dejaVu = map[Throwable]struct{}{t: {}}
   590  
   591  	// Print our stack trace
   592  	_, _ = writer.Write([]byte(fmt.Sprintln(t)))
   593  
   594  	trace := t.GetOurStackTrace()
   595  	_, _ = writer.Write(t.GetOurStackTrace())
   596  
   597  	// Print suppressed exceptions, if any
   598  	for _, se := range t.GetSuppressed() {
   599  		se.PrintEnclosedStackTrace(writer, trace, SuppressedCaption, "\t", dejaVu)
   600  	}
   601  
   602  	// Print cause, if any
   603  	ourCause := t.GetCause()
   604  	if ourCause != nil {
   605  		ourCause.PrintEnclosedStackTrace(writer, trace, CauseCaption, "", dejaVu)
   606  	}
   607  }
   608  
   609  /**
   610   * Print our stack trace as an enclosed exception for the specified
   611   * stack trace.
   612   */
   613  func (t *ThrowableObject) PrintEnclosedStackTrace(writer io.Writer, enclosingTrace []byte,
   614  	caption string, prefix string, dejaVu map[Throwable]struct{}) {
   615  	if _, has := dejaVu[t]; has {
   616  		_, _ = writer.Write([]byte(fmt.Sprintln("\t[CIRCULAR REFERENCE:", t, "]")))
   617  		return
   618  	}
   619  
   620  	dejaVu[t] = struct{}{}
   621  	// Compute number of frames in common between this and enclosing trace
   622  	trace := t.GetOurStackTrace()
   623  	traces := bytes.Split(trace, []byte{'\n'})
   624  	enclosingTraces := bytes.Split(enclosingTrace, []byte{'\n'})
   625  	m := len(traces) - 1
   626  	n := len(enclosingTraces) - 1
   627  	for m >= 0 && n >= 0 && bytes.EqualFold(traces[m], enclosingTraces[n]) {
   628  		m--
   629  		n--
   630  	}
   631  
   632  	framesInCommon := len(traces) - 1 - m
   633  
   634  	// Print our stack trace
   635  	_, _ = writer.Write([]byte(fmt.Sprintln(prefix+caption, t)))
   636  	for i := 0; i <= m; i++ {
   637  		_, _ = writer.Write([]byte(fmt.Sprintln(traces[i])))
   638  	}
   639  	if framesInCommon != 0 {
   640  		_, _ = writer.Write([]byte(fmt.Sprintln(prefix, "\t...", framesInCommon, " more")))
   641  	}
   642  
   643  	// Print suppressed exceptions, if any
   644  	for _, se := range t.GetSuppressed() {
   645  		se.PrintEnclosedStackTrace(writer, trace, SuppressedCaption, prefix+"\t", dejaVu)
   646  	}
   647  
   648  	// Print cause, if any
   649  	ourCause := t.GetCause()
   650  	if ourCause != nil {
   651  		ourCause.PrintEnclosedStackTrace(writer, trace, CauseCaption, prefix, dejaVu)
   652  	}
   653  }
   654  
   655  /**
   656   * Fills in the execution stack trace. This method records within this
   657   * {@code Throwable} object information about the current state of
   658   * the stack frames for the current thread.
   659   *
   660   * <p>If the stack trace of this {@code Throwable} {@linkplain
   661   * Throwable#Throwable(String, Throwable, boolean, boolean) is not
   662   * writable}, calling this method has no effect.
   663   *
   664   * @return  a reference to this {@code Throwable} instance.
   665   * @see     java.lang.Throwable#printStackTrace()
   666   */
   667  func (t *ThrowableObject) fillInStackTrack() Throwable {
   668  	if t.stackTrace != nil {
   669  		t.stackTrace = UnassignedStack
   670  	}
   671  	return t
   672  }
   673  
   674  /**
   675   * Provides programmatic access to the stack trace information printed by
   676   * {@link #printStackTrace()}.  Returns an array of stack trace elements,
   677   * each representing one stack frame.  The zeroth element of the array
   678   * (assuming the array's length is non-zero) represents the top of the
   679   * stack, which is the last method invocation in the sequence.  Typically,
   680   * this is the point at which this throwable was created and thrown.
   681   * The last element of the array (assuming the array's length is non-zero)
   682   * represents the bottom of the stack, which is the first method invocation
   683   * in the sequence.
   684   *
   685   * <p>Some virtual machines may, under some circumstances, omit one
   686   * or more stack frames from the stack trace.  In the extreme case,
   687   * a virtual machine that has no stack trace information concerning
   688   * this throwable is permitted to return a zero-length array from this
   689   * method.  Generally speaking, the array returned by this method will
   690   * contain one element for every frame that would be printed by
   691   * {@code printStackTrace}.  Writes to the returned array do not
   692   * affect future calls to this method.
   693   *
   694   * @return an array of stack trace elements representing the stack trace
   695   *         pertaining to this throwable.
   696   * @since  1.4
   697   */
   698  func (t *ThrowableObject) GetStackTrace() []byte {
   699  	return object.DeepClone(t.GetOurStackTrace()).([]byte)
   700  }
   701  
   702  func (t *ThrowableObject) GetOurStackTrace() []byte {
   703  	if t.stackTrace == nil {
   704  		return UnassignedStack
   705  	}
   706  
   707  	if bytes.Equal(t.stackTrace, UnassignedStack) {
   708  		t.stackTrace = debug.Stack()
   709  	}
   710  	return t.stackTrace
   711  }
   712  
   713  /**
   714   * Sets the stack trace elements that will be returned by
   715   * {@link #getStackTrace()} and printed by {@link #printStackTrace()}
   716   * and related methods.
   717   *
   718   * This method, which is designed for use by RPC frameworks and other
   719   * advanced systems, allows the client to override the default
   720   * stack trace that is either generated by {@link #fillInStackTrace()}
   721   * when a throwable is constructed or deserialized when a throwable is
   722   * read from a serialization stream.
   723   *
   724   * <p>If the stack trace of this {@code Throwable} {@linkplain
   725   * Throwable#Throwable(String, Throwable, boolean, boolean) is not
   726   * writable}, calling this method has no effect other than
   727   * validating its argument.
   728   *
   729   * @param   stackTrace the stack trace elements to be associated with
   730   * this {@code Throwable}.  The specified array is copied by this
   731   * call; changes in the specified array after the method invocation
   732   * returns will have no affect on this {@code Throwable}'s stack
   733   * trace.
   734   *
   735   * @throws NullPointerException if {@code stackTrace} is
   736   *         {@code null} or if any of the elements of
   737   *         {@code stackTrace} are {@code null}
   738   *
   739   * @since  1.4
   740   */
   741  func (t *ThrowableObject) SetStackTrace(trace []byte) {
   742  	// Validate argument
   743  	if len(trace) == 0 {
   744  		panic(NewNullPointerException1("stackTrace[]"))
   745  		return
   746  	}
   747  	if t.stackTrace == nil { // Immutable stack
   748  		return
   749  	}
   750  	defensiveCopy := object.DeepClone(trace).([]byte)
   751  	t.stackTrace = defensiveCopy
   752  }
   753  
   754  /**
   755   * Appends the specified exception to the exceptions that were
   756   * suppressed in order to deliver this exception. This method is
   757   * thread-safe and typically called (automatically and implicitly)
   758   * by the {@code try}-with-resources statement.
   759   *
   760   * <p>The suppression behavior is enabled <em>unless</em> disabled
   761   * {@linkplain #Throwable(String, Throwable, boolean, boolean) via
   762   * a constructor}.  When suppression is disabled, this method does
   763   * nothing other than to validate its argument.
   764   *
   765   * <p>Note that when one exception {@linkplain
   766   * #initCause(Throwable) causes} another exception, the first
   767   * exception is usually caught and then the second exception is
   768   * thrown in response.  In other words, there is a causal
   769   * connection between the two exceptions.
   770   *
   771   * In contrast, there are situations where two independent
   772   * exceptions can be thrown in sibling code blocks, in particular
   773   * in the {@code try} block of a {@code try}-with-resources
   774   * statement and the compiler-generated {@code finally} block
   775   * which closes the resource.
   776   *
   777   * In these situations, only one of the thrown exceptions can be
   778   * propagated.  In the {@code try}-with-resources statement, when
   779   * there are two such exceptions, the exception originating from
   780   * the {@code try} block is propagated and the exception from the
   781   * {@code finally} block is added to the list of exceptions
   782   * suppressed by the exception from the {@code try} block.  As an
   783   * exception unwinds the stack, it can accumulate multiple
   784   * suppressed exceptions.
   785   *
   786   * <p>An exception may have suppressed exceptions while also being
   787   * caused by another exception.  Whether or not an exception has a
   788   * cause is semantically known at the time of its creation, unlike
   789   * whether or not an exception will suppress other exceptions
   790   * which is typically only determined after an exception is
   791   * thrown.
   792   *
   793   * <p>Note that programmer written code is also able to take
   794   * advantage of calling this method in situations where there are
   795   * multiple sibling exceptions and only one can be propagated.
   796   *
   797   * @param exception the exception to be added to the list of
   798   *        suppressed exceptions
   799   * @throws IllegalArgumentException if {@code exception} is this
   800   *         throwable; a throwable cannot suppress itself.
   801   * @throws NullPointerException if {@code exception} is {@code null}
   802   * @since 1.7
   803   */
   804  func (t *ThrowableObject) AddSuppressed(exception Throwable) {
   805  	if exception == t {
   806  		panic(NewIllegalArgumentException2(SelfSuppressionMessage, exception))
   807  	}
   808  	if exception == nil {
   809  		panic(NewNullPointerException1(NullCauseMessage))
   810  	}
   811  	if t.suppressedExceptions == nil {
   812  		return
   813  	}
   814  	t.suppressedExceptions = append(t.suppressedExceptions, exception)
   815  }
   816  
   817  /**
   818   * Returns an array containing all of the exceptions that were
   819   * suppressed, typically by the {@code try}-with-resources
   820   * statement, in order to deliver this exception.
   821   *
   822   * If no exceptions were suppressed or {@linkplain
   823   * #Throwable(String, Throwable, boolean, boolean) suppression is
   824   * disabled}, an empty array is returned.  This method is
   825   * thread-safe.  Writes to the returned array do not affect future
   826   * calls to this method.
   827   *
   828   * @return an array containing all of the exceptions that were
   829   *         suppressed to deliver this exception.
   830   * @since 1.7
   831   */
   832  func (t *ThrowableObject) GetSuppressed() []Throwable {
   833  	if reflect.DeepEqual(t.suppressedExceptions, SuppressedSentinel) || t.suppressedExceptions == nil {
   834  		return EmptyThrowableArray
   835  	}
   836  	return t.suppressedExceptions
   837  }