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.<init>(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 }