001: /*****************************************************************************
002: * *
003: * This file is part of the BeanShell Java Scripting distribution. *
004: * Documentation and updates may be found at http://www.beanshell.org/ *
005: * *
006: * Sun Public License Notice: *
007: * *
008: * The contents of this file are subject to the Sun Public License Version *
009: * 1.0 (the "License"); you may not use this file except in compliance with *
010: * the License. A copy of the License is available at http://www.sun.com *
011: * *
012: * The Original Code is BeanShell. The Initial Developer of the Original *
013: * Code is Pat Niemeyer. Portions created by Pat Niemeyer are Copyright *
014: * (C) 2000. All Rights Reserved. *
015: * *
016: * GNU Public License Notice: *
017: * *
018: * Alternatively, the contents of this file may be used under the terms of *
019: * the GNU Lesser General Public License (the "LGPL"), in which case the *
020: * provisions of LGPL are applicable instead of those above. If you wish to *
021: * allow use of your version of this file only under the terms of the LGPL *
022: * and not to allow others to use your version of this file under the SPL, *
023: * indicate your decision by deleting the provisions above and replace *
024: * them with the notice and other provisions required by the LGPL. If you *
025: * do not delete the provisions above, a recipient may use your version of *
026: * this file under either the SPL or the LGPL. *
027: * *
028: * Patrick Niemeyer (pat@pat.net) *
029: * Author of Learning Java, O'Reilly & Associates *
030: * http://www.pat.net/~pat/ *
031: * *
032: *****************************************************************************/package bsh;
033:
034: /**
035: EvalError indicates that we cannot continue evaluating the script
036: or the script has thrown an exception.
037:
038: EvalError may be thrown for a script syntax error, an evaluation
039: error such as referring to an undefined variable, an internal error.
040: <p>
041:
042: @see TargetError
043: */
044: public class EvalError extends Exception {
045: SimpleNode node;
046:
047: // Note: no way to mutate the Throwable message, must maintain our own
048: String message;
049:
050: CallStack callstack;
051:
052: public EvalError(String s, SimpleNode node, CallStack callstack) {
053: setMessage(s);
054: this .node = node;
055: // freeze the callstack for the stack trace.
056: if (callstack != null)
057: this .callstack = callstack.copy();
058: }
059:
060: /**
061: Print the error with line number and stack trace.
062: */
063: public String toString() {
064: String trace;
065: if (node != null)
066: trace = " : at Line: " + node.getLineNumber()
067: + " : in file: " + node.getSourceFile() + " : "
068: + node.getText();
069: else
070: // Users should not normally see this.
071: trace = ": <at unknown location>";
072:
073: if (callstack != null)
074: trace = trace + "\n" + getScriptStackTrace();
075:
076: return getMessage() + trace;
077: }
078:
079: /**
080: Re-throw the error, prepending the specified message.
081: */
082: public void reThrow(String msg) throws EvalError {
083: prependMessage(msg);
084: throw this ;
085: }
086:
087: /**
088: The error has trace info associated with it.
089: i.e. It has an AST node that can print its location and source text.
090: */
091: SimpleNode getNode() {
092: return node;
093: }
094:
095: void setNode(SimpleNode node) {
096: this .node = node;
097: }
098:
099: public String getErrorText() {
100: if (node != null)
101: return node.getText();
102: else
103: return "<unknown error>";
104: }
105:
106: public int getErrorLineNumber() {
107: if (node != null)
108: return node.getLineNumber();
109: else
110: return -1;
111: }
112:
113: public String getErrorSourceFile() {
114: if (node != null)
115: return node.getSourceFile();
116: else
117: return "<unknown file>";
118: }
119:
120: public String getScriptStackTrace() {
121: if (callstack == null)
122: return "<Unknown>";
123:
124: String trace = "";
125: CallStack stack = callstack.copy();
126: while (stack.depth() > 0) {
127: NameSpace ns = stack.pop();
128: SimpleNode node = ns.getNode();
129: if (ns.isMethod) {
130: trace = trace + "\nCalled from method: " + ns.getName();
131: if (node != null)
132: trace += " : at Line: " + node.getLineNumber()
133: + " : in file: " + node.getSourceFile()
134: + " : " + node.getText();
135: }
136: }
137:
138: return trace;
139: }
140:
141: /**
142: @see #toString() for a full display of the information
143: */
144: public String getMessage() {
145: return message;
146: }
147:
148: public void setMessage(String s) {
149: message = s;
150: }
151:
152: /**
153: Prepend the message if it is non-null.
154: */
155: protected void prependMessage(String s) {
156: if (s == null)
157: return;
158:
159: if (message == null)
160: message = s;
161: else
162: message = s + " : " + message;
163: }
164:
165: }
|