1  /*
     2   * Copyright the original author or authors.
     3   * 
     4   * Licensed under the MOZILLA PUBLIC LICENSE, Version 1.1 (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.mozilla.org/MPL/MPL-1.1.html
     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  
    17  import org.as2lib.core.BasicInterface;
    18  
    19  /**
    20   * {@code Throwable} is the basic interface for every class that is thrown.
    21   *
    22   * <p>You can actually throw every class even if it does not implement this interface
    23   * but it is recommended to strictly use this interface for every throwable. Using it
    24   * produces clarity and setups a standard.
    25   *
    26   * <p>It prescribes implementing classes to provide key functionalities that help you
    27   * a lot when an exception is thrown and you do not catch it.
    28   * 
    29   * <p>The first thing is the message. The message contains detaild information about
    30   * the problem that occurred and is inteded for developers, not for users.
    31   * 
    32   * <p>The second is the stack trace. The stack trace contains at least the method that
    33   * actually threw the throwable. It can also contain the method that invoked the
    34   * method that threw the throwable and so on.
    35   * 
    36   * <p>The third feature is the cause. Let's say a throwable is thrown and you catch it.
    37   * After catching it you want to throw a new throwable, that is of another type (maybe
    38   * a application specific exception while the catched was a generic one from a framework)
    39   * and contains another message that describes the problem from the point of view of
    40   * the catching method. In such a case we of course do not want to lose the
    41   * information the catched throwable provides, that caused the throwing of the new
    42   * throwable. We thus create the new throwable and initialize its cause, the catched
    43   * throwable, to get a more comprehensive error message.
    44   * 
    45   * <p>The fourth is the error code. While the message is inteded for developers, the
    46   * error code can be used to get localized messages from a message source that are
    47   * intended for users.
    48   *
    49   * <p>Working with throwables in ActionScript is a little buggy and can be a pain to
    50   * use if you do not know to what you have to pay attention.
    51   *
    52   * <p>The first thing is that if you catch a throwable, the type of it must be fully
    53   * qualified. You cannot import the throwable and then only use its name, because
    54   * Flash will then not recognize the type, and will not catch the thrown throwable
    55   * (Note that it actually works when working on the timeline. The problem only occures
    56   * within classes. But I would nevertheless always use fully qualified names to guard
    57   * against potential errors.). Thus write your catch-blocks always the following way.
    58   * <code>
    59   *   try {
    60   *       ...
    61   *   } catch (e:org.as2lib.env.except.IllegalArgumentException) {
    62   *       ...
    63   *   }
    64   * </code>
    65   *
    66   * <p>The second problem occurs when working with Flex. The throwable type in the
    67   * catch-block's signature must always be a sub-class of the class {@code Error}
    68   * (which is the native 'throwable' of ActionScript). Because of that it is not
    69   * possible to catch throwables by interfaces, like this interface. If you simply want
    70   * to catch all throwables that may be thrown in your application do not specify a
    71   * throwable type or use {@code Error} if you are really really sure that all your
    72   * concrete throwable implementations extend this class. Note that the
    73   * {@link Exception} and {@link FatalException} classes extend the {@code Error} class,
    74   * so they and any sub-classes can be used with Flex.
    75   * 
    76   * @author Simon Wacker
    77   * @see <a href="http://www.as2lib.org/documentation/articles/as2lib_exception_api">Exceptions</a>
    78   */
    79  interface org.as2lib.env.except.Throwable extends BasicInterface {
    80  	
    81  	/**
    82  	 * Returns an array that contains {@link StackTraceElement} instances of the
    83  	 * methods invoked before this throwable was thrown.
    84  	 *
    85  	 * <p>The last element is always the one that contains the actual method that
    86  	 * threw the throwable.
    87  	 *
    88  	 * <p>The stack trace helps you a lot because it says you where the throwing of
    89  	 * the throwable took place and also what arguments caused the throwing.
    90  	 *
    91  	 * @return a stack containing the invoked methods until the throwable was thrown
    92  	 */
    93  	public function getStackTrace(Void):Array;
    94  	
    95  	/**
    96  	 * Adds a stack trace element to the stack trace.
    97  	 *
    98  	 * <p>The new stack trace element is added to the end of the stack trace.
    99  	 *
   100  	 * <p>At some parts in your application you may want to add stack trace elements
   101  	 * manually. This can help you to get a clearer image of what went where wrong and
   102  	 * why. You can use this method to do so.
   103  	 *
   104  	 * @param thrower the object that threw, rethrew or forwarded (let pass) the
   105  	 * throwable
   106  	 * @param method the method that threw, rethrew or forwarded (let pass) the
   107  	 * throwable
   108  	 * @param args the arguments the method was invoked with when throwing, rethrowing
   109  	 * or forwarding (leting pass) the throwable
   110  	 */
   111  	public function addStackTraceElement(thrower, method:Function, args:Array):Void;
   112  	
   113  	/**
   114  	 * Initializes the cause of this throwable.
   115  	 *
   116  	 * <p>The cause can only be initialized once. You normally initialize a cause if
   117  	 * you throw a throwable due to the throwing of another throwable. Thereby you do
   118  	 * not lose the information the cause offers.
   119  	 * 
   120  	 * <p>This method returns this throwable to have an easy way to initialize the
   121  	 * cause. Following is how you could use the cause mechanism.
   122  	 *
   123  	 * <code>
   124  	 *   try {
   125  	 *       myInstance.invokeMethodThatThrowsAThrowable();
   126  	 *   } catch (e:org.as2lib.env.except.Throwable) {
   127  	 *       throw new MyThrowable("myMessage", this, arguments).initCause(e);
   128  	 *   }
   129  	 * </code>
   130  	 * 
   131  	 * @param cause the throwable that caused the throwing of this throwable
   132  	 * @return this throwable itself
   133  	 * @throws org.as2lib.env.except.IllegalStateException if the cause has already
   134  	 * been initialized
   135  	 */
   136  	public function initCause(cause):Throwable;
   137  	
   138  	/**
   139  	 * Returns the initialized cause.
   140  	 *
   141  	 * <p>The cause is the throwable that caused this throwable to be thrown.
   142  	 *
   143  	 * @return the initialized cause
   144  	 * @see #initCause
   145  	 */
   146  	public function getCause(Void);
   147  	
   148  	/**
   149  	 * Returns the message that describes in detail what went wrong.
   150  	 *
   151  	 * <p>The message should be understandable, even for non-programmers. It should
   152  	 * contain detailed information about what went wrong. And maybe also how the user
   153  	 * that sees this message can solve the problem.
   154  	 *
   155  	 * <p>If the throwable was thrown for example because of a wrong collaborator or
   156  	 * an illegal string or something similar, provide the string representation of it
   157  	 * in the error message. It is recommended to put these between []-characters.
   158  	 *
   159  	 * @return the message that describes the problem in detail
   160  	 */
   161  	public function getMessage(Void):String;
   162  	
   163  	/**
   164  	 * Initializes the error code for this throwable.
   165  	 * 
   166  	 * <p>The initialization works only once. Any further initialization results in an
   167  	 * exception.
   168  	 * 
   169  	 * <p>Take a look at {@link #getErrorCode} to see what error codes are good for.
   170  	 * 
   171  	 * @param errorCode the error code to get localized client messages by
   172  	 * @return this throwable
   173  	 * @see #getErrorCode
   174  	 */
   175  	public function initErrorCode(errorCode:String):Throwable;
   176  	
   177  	/**
   178  	 * Returns the initialized error code.
   179  	 * 
   180  	 * <p>Error codes can be used to obtain localized messages appropriate for users;
   181  	 * while the {@link #getMessage} method returns messages inteded for developers to
   182  	 * get hands on the exception and fix bugs more easily.
   183  	 * The localized messages can for example be obtained through a global message
   184  	 * source and property files.
   185  	 * 
   186  	 * @return the error code to obtain an error message for users
   187  	 */
   188  	public function getErrorCode(Void):String;
   189  	
   190  }