com.gargoylesoftware.htmlunit.ScriptException Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of xlt Show documentation
Show all versions of xlt Show documentation
XLT (Xceptance LoadTest) is an extensive load and performance test tool developed and maintained by Xceptance.
/*
* Copyright (c) 2002-2021 Gargoyle Software Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.gargoylesoftware.htmlunit;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.StringTokenizer;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import net.sourceforge.htmlunit.corejs.javascript.EcmaError;
import net.sourceforge.htmlunit.corejs.javascript.JavaScriptException;
import net.sourceforge.htmlunit.corejs.javascript.RhinoException;
import net.sourceforge.htmlunit.corejs.javascript.WrappedException;
/**
* An exception that will be thrown if an error occurs during the processing of
* a script.
*
* @author Mike Bowler
* @author Marc Guillemot
* @author Frank Danek
*/
public class ScriptException extends RuntimeException {
private final String scriptSourceCode_;
private final HtmlPage page_;
/**
* Creates an instance.
* @param page the page in which the script causing this exception was executed
* @param throwable the exception that was thrown from the script engine
* @param scriptSourceCode the code that was being executed when this exception
* was thrown. This may be null if the exception was not caused by execution
* of JavaScript.
*/
public ScriptException(final HtmlPage page, final Throwable throwable,
final String scriptSourceCode) {
super(getMessageFrom(throwable), throwable);
scriptSourceCode_ = scriptSourceCode;
page_ = page;
}
private static String getMessageFrom(final Throwable throwable) {
if (throwable == null) {
return "null";
}
return throwable.getMessage();
}
/**
* Creates an instance.
* @param page the page in which the script causing this exception was executed
* @param throwable the exception that was thrown from the script engine
*/
public ScriptException(final HtmlPage page, final Throwable throwable) {
this(page, throwable, null);
}
/**
* Prints the stack trace to System.out. If this exception contains another
* exception then the stack traces for both will be printed.
*/
@Override
public void printStackTrace() {
printStackTrace(System.out);
}
/**
* Prints the stack trace. If this exception contains another exception then
* the stack traces for both will be printed.
*
* @param writer Where the stack trace will be written
*/
@Override
public void printStackTrace(final PrintWriter writer) {
writer.write(createPrintableStackTrace());
}
/**
* Prints the stack trace. If this exception contains another exception then
* the stack traces for both will be printed.
*
* @param stream Where the stack trace will be written
*/
@Override
public void printStackTrace(final PrintStream stream) {
stream.print(createPrintableStackTrace());
}
private String createPrintableStackTrace() {
final StringWriter stringWriter = new StringWriter();
final PrintWriter printWriter = new PrintWriter(stringWriter);
printWriter.println("======= EXCEPTION START ========");
if (getCause() != null) {
if (getCause() instanceof EcmaError) {
final EcmaError ecmaError = (EcmaError) getCause();
printWriter.print("EcmaError: ");
printWriter.print("lineNumber=[");
printWriter.print(ecmaError.lineNumber());
printWriter.print("] column=[");
printWriter.print(ecmaError.columnNumber());
printWriter.print("] lineSource=[");
printWriter.print(getFailingLine());
printWriter.print("] name=[");
printWriter.print(ecmaError.getName());
printWriter.print("] sourceName=[");
printWriter.print(ecmaError.sourceName());
printWriter.print("] message=[");
printWriter.print(ecmaError.getMessage());
printWriter.print("]");
printWriter.println();
}
else {
printWriter.println("Exception class=[" + getCause().getClass().getName() + "]");
}
}
super.printStackTrace(printWriter);
if (getCause() instanceof JavaScriptException) {
final Object value = ((JavaScriptException) getCause()).getValue();
printWriter.print("JavaScriptException value = ");
if (value instanceof Throwable) {
((Throwable) value).printStackTrace(printWriter);
}
else {
printWriter.println(value);
}
}
else if (getCause() instanceof WrappedException) {
final WrappedException wrappedException = (WrappedException) getCause();
printWriter.print("WrappedException: ");
wrappedException.printStackTrace(printWriter);
final Throwable innerException = wrappedException.getWrappedException();
if (innerException == null) {
printWriter.println("Inside wrapped exception: null");
}
else {
printWriter.println("Inside wrapped exception:");
innerException.printStackTrace(printWriter);
}
}
else if (getCause() != null) {
printWriter.println("Enclosed exception: ");
getCause().printStackTrace(printWriter);
}
if (scriptSourceCode_ != null && !scriptSourceCode_.isEmpty()) {
printWriter.println("== CALLING JAVASCRIPT ==");
printWriter.println(scriptSourceCode_);
}
printWriter.println("======= EXCEPTION END ========");
return stringWriter.toString();
}
/**
* Returns the source code line that failed.
* @return the source code line that failed
*/
public String getScriptSourceCode() {
return scriptSourceCode_;
}
/**
* Returns the line of source that was being executed when this exception was
* thrown.
*
* @return the line of source or an empty string if the exception was not thrown
* due to the execution of a script.
*/
public String getFailingLine() {
final int lineNumber = getFailingLineNumber();
if (lineNumber == -1 || scriptSourceCode_ == null) {
return "";
}
try (BufferedReader reader = new BufferedReader(new StringReader(scriptSourceCode_))) {
for (int i = 0; i < lineNumber - 1; i++) {
reader.readLine();
}
return reader.readLine();
}
catch (final IOException e) {
// Theoretically impossible
e.printStackTrace();
}
return "";
}
/**
* Returns the line number of the source that was executing at the time of the exception.
*
* @return the line number or -1 if the exception was not thrown due to the
* execution of a script.
*/
public int getFailingLineNumber() {
if (getCause() instanceof RhinoException) {
final RhinoException cause = (RhinoException) getCause();
return cause.lineNumber();
}
return -1;
}
/**
* Returns the column number of the source that was executing at the time of the exception.
*
* @return the column number or -1 if the exception was not thrown due to the
* execution of a script.
*/
public int getFailingColumnNumber() {
if (getCause() instanceof RhinoException) {
final RhinoException cause = (RhinoException) getCause();
return cause.columnNumber();
}
return -1;
}
/**
* Gets the HTML page in which the script error occurred.
* Caution: this page may be only partially parsed if the exception occurred in a script
* executed at parsing time.
* @return the page
*/
public HtmlPage getPage() {
return page_;
}
/**
* Prints the script stack trace.
* This represents only the script calls.
* @param writer where the stack trace will be written
*/
public void printScriptStackTrace(final PrintWriter writer) {
final StringWriter stringWriter = new StringWriter();
final PrintWriter printWriter = new PrintWriter(stringWriter);
getCause().printStackTrace(printWriter);
writer.print(getCause().getMessage());
final StringTokenizer st = new StringTokenizer(stringWriter.toString(), "\r\n");
while (st.hasMoreTokens()) {
final String line = st.nextToken();
if (line.contains("at script")) {
writer.println();
writer.print(line.replaceFirst("at script\\.?", "at "));
}
}
}
}