001: // Copyright © 2002-2007 Canoo Engineering AG, Switzerland.
002: package com.canoo.webtest.steps;
003:
004: import java.io.PrintWriter;
005: import java.io.StringWriter;
006: import java.lang.reflect.InvocationTargetException;
007: import java.net.SocketTimeoutException;
008:
009: import org.apache.log4j.Logger;
010: import org.apache.xerces.xni.XNIException;
011: import org.xml.sax.SAXException;
012:
013: import com.canoo.webtest.engine.StepExecutionException;
014: import com.canoo.webtest.engine.StepFailedException;
015: import com.canoo.webtest.engine.WebTestException;
016: import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
017: import com.gargoylesoftware.htmlunit.ScriptException;
018: import com.gargoylesoftware.htmlunit.html.HtmlPage;
019:
020: /**
021: * Helper class for {@link Step}.
022: * @author Carsten Seibert
023: * @author Marc Guillemot
024: * @author Paul King
025: */
026: public class StepUtil {
027: private static final Logger LOG = Logger.getLogger(StepUtil.class);
028:
029: static Throwable extractNestedException(final Throwable e) {
030: Throwable originalException = e;
031: Throwable cause = ((XNIException) e).getException();
032: while (cause != null) {
033: originalException = cause;
034: if (cause instanceof XNIException) {
035: cause = ((XNIException) cause).getException();
036: } else if (cause instanceof InvocationTargetException) {
037: cause = cause.getCause();
038: } else {
039: cause = null;
040: }
041: }
042: return originalException;
043: }
044:
045: /**
046: * Called if {@link Step#doExecute()} throws an exception
047: * @param e the thrown exception
048: */
049: public static void handleException(Throwable e) {
050: if (e instanceof WebTestException) {
051: throw (WebTestException) e;
052: } else if (e instanceof FailingHttpStatusCodeException) {
053: LOG
054: .debug("Wrapping FailingHttpStatusCodeException in StepFailedException: "
055: + e.getMessage());
056: final FailingHttpStatusCodeException he = (FailingHttpStatusCodeException) e;
057: throw new StepFailedException("HTTP error "
058: + he.getStatusCode(), he);
059: } else if (e instanceof ScriptException) {
060: final ScriptException se = (ScriptException) e;
061: final HtmlPage page = se.getPage(); // should normally not be null but it happens in HtmlUnit 1.14 ;-(
062: final StepFailedException sfe = new StepFailedException(
063: "JavaScript error loading page "
064: + (page != null ? page.getWebResponse()
065: .getUrl().toString() : "") + ": "
066: + se.getMessage(), se);
067: sfe.addDetail("javascript error", se.getMessage());
068: sfe.addDetail("line", String.valueOf(se
069: .getFailingLineNumber()));
070: sfe
071: .addDetail("javascript source", se
072: .getScriptSourceCode());
073: sfe.addDetail("failing line", se.getFailingLine());
074:
075: // the javascript call stack
076: final StringWriter stringWriter = new StringWriter();
077: final PrintWriter printWriter = new PrintWriter(
078: stringWriter);
079: se.printScriptStackTrace(printWriter);
080: sfe.addDetail("javascript call stack", stringWriter
081: .toString());
082:
083: throw sfe;
084: } else if (e instanceof SocketTimeoutException) {
085: final SocketTimeoutException ste = (SocketTimeoutException) e;
086: throw new StepFailedException(
087: "Server took to long to answer: "
088: + ste.getMessage(), ste);
089: } else if (e instanceof SAXException) {
090: throw new StepExecutionException(
091: "Response is not well-formed: " + e.getMessage(), e);
092: } else if (e instanceof XNIException) { // XNIException are not helpful, we need to extract the deeply
093: // nested original exception
094: final Throwable originalException = StepUtil
095: .extractNestedException(e);
096: throw new StepExecutionException("XNIException caused by "
097: + originalException.getMessage(), originalException);
098: }
099: // TODO: See WT-194 should we catch java.io.IOException here and rethrow
100: // as
101: // StepFailed with message 'Server closed connection'? This would allow
102: // retry around this situation
103:
104: throw new StepExecutionException(
105: "Unexpected exception caught: "
106: + e.getClass().getName(), e);
107: }
108: }
|