Package Torello.Java

Class EXCC


  • public class EXCC
    extends java.lang.Object
    'Exception Cause Chain' helps convert exception messages whose Throwable.cause() method returns a non-null cause, thereby unrolling (and printing) this chain of exceptions into a readable String.

    EXCC: Exception Cause Chain


    The acronym "EXCC" stands for the words "Exception Cause Chain". In Java, there are a few (very few) places where the web-scraping is benefited by a multi-threaded environment. In such cases, exceptions that are generated/thrown in your code, may have been thrown by a different thread. One of Java's strengths is that multi-threaded code was quite developed for the JRE, and that includes exceptions. In Java, Exception's thrown by a different thread will often be wrapped into another Exception. To retrieve the "cause," simply invoke Exception.getCause() to get the Exception that was thrown in the other thread.

    Java does not expect every exception throw to provide a "cause" - quite the contrary, most do not. There are also a number of java Exception's that do not even allow for a "cause throwable" in any of the provided constructors. Multi-threaded code is on source of "exception chaining" - but code there are also instances where simple try-catchblocks will catch an exceptions and wrap it (and throw the new Exception instance) in order to give the Exception a different name, and also to provide more detailed information about the error that has occurred.

    Either way, printing such information is easier to read if there is a standardized formatting for such information. This is the intended purpose to class EXCC

    ASIDE: An example that may be found multi-threaded code where one thread "monitoring" another to prevent program execution progress from "hanging" because of an internet connection would be Java's class TimeOutException and it's class ExecutionException. When java throws a time-out exception, it usually means that the underlying thread timed-out, and no "cause exception chain" is needed. However, there are also situations where java will use the class ExecutionException, because the monitor-thread detected a crash. Here, finding out which exception that the monitor thread actually caught (and wrapped inside instance class ExecutionException) requires looking at the 'ExecutionException.getCause();' throwable-chain.

    In this case, an exception from another thread will actually have two different stack-traces:

    1. ex.printStackTrace();
    2. ex.getCause().printStackTrace();

    FURTHER-ASIDE: Generally the nuts-and-bolts of Java's IO network communications exceptions are not very interesting. However, if viewing the "getCause()" of an exception has become important, this class will help print the cause-exception (and even its causes' cause - recursively). The String-methods in this class use recursion to traverse through each "parent exception", adding indentations, until a null getCause() is returned.



    Stateless Class:
    This class neither contains any program-state, nor can it be instantiated. The @StaticFunctional Annotation may also be called 'The Spaghetti Report'. Static-Functional classes are, essentially, C-Styled Files, without any constructors or non-static member fields. It is a concept very similar to the Java-Bean's @Stateless Annotation.
    • 1 Constructor(s), 1 declared private, zero-argument constructor
    • 3 Method(s), 3 declared static
    • 0 Field(s)


    • Method Summary

       
      Print Exception and, recursively, all causes to a String
      Modifier and Type Method
      static String toString​(Throwable t)
      static String toString​(Throwable t, int indentation)
       
      Print Exceptions recursively, but do not print Stack-Traces
      Modifier and Type Method
      static String toStringNoST​(Throwable t)
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Method Detail

      • toString

        🡅  🡇    
        public static java.lang.String toString​(java.lang.Throwable t)
        Prints the Exception-message and Exception-stack trace to an output String, and invokes, recursively, this method with any cause-Throwable's that are present in this Throwable.
        Parameters:
        t - Any Java Throwable
        Returns:
        This method doesn't actually print anything to the screen or terminal, it just returns a String that you may print yourself - or write to a class StringBuilder, or any variation of text-output you wish.
        Code:
        Exact Method Body:
         StackTraceElement[] steArr      = t.getStackTrace();
         StringBuilder       sb          = new StringBuilder();
         Throwable           cause       = t.getCause();
         String              m           = t.getMessage();
         String              lm          = t.getLocalizedMessage();
         boolean             hasMessage  = (m != null) && (m.length() > 0);
         boolean             hasLMess    = (lm != null) && (lm.length() > 0);
        
         if (hasMessage) m   = StrIndent.indent(m, 1, false, true);
         if (hasLMess)   lm  = StrIndent.indent(lm, 1, false, true);
        
         sb.append(BRED + "THROWN: " + t.getClass().getCanonicalName() + RESET + "\n");
        
         if (hasMessage)
         {
             sb.append(BCYAN + "Throwable.getMessage():\n" + RESET + m + "\n");
        
             if (hasLMess && (! m.equals(lm)))
                 sb.append(BCYAN + "Throwable.getLocalizedMessage():\n" + RESET + lm + "\n");
         }
        
         else if (hasLMess)
             sb.append(BCYAN + "Throwable.getLocalizedMessage():\n" + RESET + lm + "\n");
        
         else
             sb.append(BYELLOW + "No Exception Messages Provided.\n" + RESET);
        
         sb.append(BCYAN + "StackTrace:\n" + RESET);
        
         int temp, maxLN = 0;
        
         for (StackTraceElement ste : steArr)
        
             if ((temp = ste.getLineNumber()) > maxLN)
                 maxLN = temp;
        
         int base10 = 2 /* 2: colon + space */ + ((int) Math.ceil(Math.log10(maxLN)));
        
         for (int k=0; k < steArr.length; k++)
        
             sb.append(
                 '\t' + StringParse.rightSpacePad(steArr[k].getLineNumber() + ":", base10) +
                 steArr[k].getClassName() + "." +
                 steArr[k].getMethodName() + "()\n"
             );
        
         return (cause == null)
             ? sb.toString()
             : sb.toString() + StrIndent.indentTabs(toString(cause), 1);
        
      • toStringNoST

        🡅    
        public static java.lang.String toStringNoST​(java.lang.Throwable t)
        Prints the Exception-message to an output String. Invokes, recursively, this method with any cause-Throwable's that are present in this Throwable.

        This method differs from toString(Throwable), in that it does not print the StackTrace's to the output String.
        Parameters:
        t - Any Java Throwable
        Returns:
        This method doesn't actually print anything to the screen or terminal, it just returns a String that you may print yourself - or write to a class StorageBuffer, or any variation of logging you wish.
        Code:
        Exact Method Body:
         StringBuilder       sb          = new StringBuilder();
         Throwable           cause       = t.getCause();
         String              m           = t.getMessage();
         String              lm          = t.getLocalizedMessage();
         boolean             hasMessage  = (m != null) && (m.length() > 0);
         boolean             hasLMess    = (lm != null) && (lm.length() > 0);
        
         if (hasMessage) m   = StrIndent.indent(m, 1, false, true);
         if (hasLMess)   lm  = StrIndent.indent(lm, 1, false, true);
        
         sb.append(BRED + "THROWN: " + t.getClass().getCanonicalName() + RESET + "\n");
        
         if (hasMessage)
         {
             sb.append(BCYAN + "Throwable.getMessage():\n" + RESET + m + "\n");
        
             if (hasLMess && (! m.equals(lm)))
                 sb.append(BCYAN + "Throwable.getLocalizedMessage():\n" + RESET + lm + "\n");
         }
        
         else if (hasLMess)
             sb.append(BCYAN + "Throwable.getLocalizedMessage():\n" + RESET + lm + "\n");
        
         else
             sb.append(BYELLOW + "No Exception Messages Provided.\n" + RESET);
        
         return (cause == null)
             ? sb.toString()
             : sb.toString() + StrIndent.indentTabs(toStringNoST(cause), 1);