Package org.auraframework.throwable

Source Code of org.auraframework.throwable.AuraExceptionUtil

/*
* Copyright (C) 2013 salesforce.com, 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
*
*         http://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 org.auraframework.throwable;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.List;

import org.auraframework.Aura;
import org.auraframework.system.Location;
import org.auraframework.throwable.quickfix.QuickFixException;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;

/**
* Utility class for Exceptiony things.
*/
public final class AuraExceptionUtil {
    //private static final Logger _log = LoggerFactory.getLogger(AuraExceptionUtil.class);

    public static String getStackTrace(Throwable th) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        th.printStackTrace(pw);
        return sw.toString();
    }

    /**
     * jams a aura location into the stacktrace of a throwable
     */
    public static void addLocation(Location location, Throwable t) {
        if (location != null) {
            StackTraceElement[] oldTrace = t.getStackTrace();
            StackTraceElement[] trace = new StackTraceElement[oldTrace.length + 1];
            StackTraceElement loc = new StackTraceElement("", "", location.getFileName(), location.getLine());
            trace[0] = loc;
            for (int i = 0; i < oldTrace.length; i++) {
                trace[i + 1] = oldTrace[i];
            }
            t.setStackTrace(trace);
        }
    }

    /**
     * Get a component stack from the context service.
     *
     * This will return a component stack, or null if there is none.
     *
     * @return a list of component descriptor + attributes.
     */
    public static List<String> getComponentStack() {
        try {
            if (Aura.getContextService() != null && Aura.getContextService().getCurrentContext() != null) {
                return Aura.getContextService().getCurrentContext().createComponentStack();
            }
        } catch (Throwable t) {
            //_log.error("Unable to get component stack", t);
        }
        return null;
    }

    /**
     * Add a component stack to an exception.
     *
     * This should arguably be a nesting exception, but that will require a larger refactor.
     * see: W-2372563
     *
     * @param t the throwable where we will insert the stack.
     * @param componentStack the stack of components in the error.
     */
    public static List<String> addComponentStack(Throwable t, List<String> componentStack) {
        if (componentStack == null) {
            return componentStack;
        }
        StackTraceElement[] oldTrace = t.getStackTrace();
        StackTraceElement[] trace = new StackTraceElement[oldTrace.length + componentStack.size()];
        int i = 0;

        for (String comp : componentStack) {
            trace[i++] = new StackTraceElement("", "", comp, 1);
        }
        for (int j = 0; j < oldTrace.length; j++) {
            trace[i + j] = oldTrace[j];
        }
        t.setStackTrace(trace);
        return componentStack;
    }

    /**
     * Try really hard to find a QuickFixException.
     *
     * This routine will attempt to unwrap any Aura exception nested inside
     * other exceptions. It is intended to handle things like Memoization or
     * Excecution exceptions, surfacing the underlying Aura exception. Note that
     * this can hide the actual exception chain.
     *
     * @param t a Throwable to check.
     * @return the original QuickFixException if the Throwable or a cause is a
     *         quick fix
     * @throws Error original Error if the Throwable or a cause is an error.
     * @throws AuraRuntimeException for any other Throwable.
     */
    public static QuickFixException passQuickFix(Throwable t) throws AuraRuntimeException, Error {
        Throwable recurse = t;
        AuraRuntimeException unwrapped = null;
        int count = 5;

        while ((recurse != null) && (count-- > 0)) {
            if (recurse instanceof QuickFixException) {
                return (QuickFixException) recurse;
            } else if ((unwrapped == null) && (recurse instanceof AuraRuntimeException)) {
                unwrapped = (AuraRuntimeException) recurse;
            } else if (recurse instanceof Error) {
                throw (Error) recurse;
            }
            recurse = recurse.getCause();
        }
        if (unwrapped != null) {
            throw unwrapped;
        }
        if (t instanceof AuraRuntimeException) {
            throw (AuraRuntimeException) t;
        }
        throw new AuraRuntimeException(t);
    }

    /**
     * Wrap an exception thrown inside plug-in code.
     *
     * Whenever a plug-in is called in Java, the caller MUST handle all
     * exceptions, and wrap things as follows:
     * <ul>
     * <li>Quick-Fixes should be passed through untouched (they will either be
     * handled, or reported as an application error)</li>
     * <li>AuraHandledException should be passed through untouched. It is an
     * error intended for the client, and should not be wrapped.</li>
     * <li>Any other AuraRuntimeException should be wrapped in a
     * AuraExecutionException (note, if these hide a quick-fix or other
     * exception, those exceptions should be surfaced).</li>
     * <li>All non-aura exceptions should also be wrapped in a
     * AuraExecutionException</li>
     * <li>If there is an error somewhere in the set of causes, surface that.</li>
     * </ul>
     *
     * Returning a QuickFixException allows the caller to do a:
     * <code>throw AuraExceptionUtil.wrapExcecutionException(t,l)</code> making
     * the calling code more obvious (we are always throwing an exception).
     *
     * @param t the exception to wrap/return.
     * @param l the location of the execution.
     * @return a quick fix exception
     * @throws AuraRuntimeException (actually a subclass of this) if there is no
     *             Quick-Fix
     * @throws Error if an error was thrown.
     */
    public static QuickFixException wrapExecutionException(Throwable t, Location l) {
        Throwable recurse = t;
        int count = 5;

        while ((recurse != null) && (count-- > 0)) {
            if (recurse instanceof QuickFixException) {
                return (QuickFixException) recurse;
            } else if (recurse instanceof AuraHandledException) {
                // Short circuit out, assume that the thrower knew what they
                // were doing.
                throw (AuraHandledException) recurse;
            } else if (recurse instanceof Error) {
                // unwrap errors, ignoring anyone else's attempt to wrap.
                throw (Error) recurse;
            }
            recurse = recurse.getCause();
        }
        throw new AuraExecutionException(t, l);
    }

    /**
     * Wrap an exception thrown inside plug-in code, not allowing a quick-fix.
     *
     * This is a very simple wrapper around {@link #wrapExecutionException}
     *
     * @param t the exception to wrap/return.
     * @param l the location of the execution.
     * @return a wrapped quick-fix exception
     * @throws AuraRuntimeException (actually a subclass of this) if there is no
     *             Quick-Fix
     * @throws Error if an error was thrown.
     */
    public static AuraRuntimeException wrapExecutionExceptionNoQFE(Throwable t, Location l) {
        QuickFixException unwrapped = wrapExecutionException(t, l);
        return new AuraUnhandledException("Unexpected exception", unwrapped);
    }
}
TOP

Related Classes of org.auraframework.throwable.AuraExceptionUtil

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.