Search in sources :

Example 6 with CancelCommandException

use of com.laytonsmith.core.exceptions.CancelCommandException in project CommandHelper by EngineHub.

the class CClosure method execute.

/**
 * Executes the closure, giving it the supplied arguments. {@code values} may be null, which means that no arguments
 * are being sent.
 *
 * LoopManipulationExceptions will never bubble up past this point, because they are never allowed, so they are
 * handled automatically, but other ProgramFlowManipulationExceptions will, . ConfigRuntimeExceptions will also
 * bubble up past this, since an execution mechanism may need to do custom handling.
 *
 * A typical execution will include the following code:
 * <pre>
 * try {
 *	closure.execute();
 * } catch(ConfigRuntimeException e){
 *	ConfigRuntimeException.HandleUncaughtException(e);
 * } catch(ProgramFlowManipulationException e){
 *	// Ignored
 * }
 * </pre>
 *
 * @param values The values to be passed to the closure
 * @throws ConfigRuntimeException If any call inside the closure causes a CRE
 * @throws ProgramFlowManipulationException If any ProgramFlowManipulationException is thrown (other than a
 * LoopManipulationException) within the closure
 * @throws FunctionReturnException If the closure has a return() call in it.
 */
public void execute(Construct... values) throws ConfigRuntimeException, ProgramFlowManipulationException, FunctionReturnException, CancelCommandException {
    if (node == null) {
        return;
    }
    StackTraceManager stManager = env.getEnv(GlobalEnv.class).GetStackTraceManager();
    stManager.addStackTraceElement(new ConfigRuntimeException.StackTraceElement("<<closure>>", getTarget()));
    try {
        Environment environment;
        synchronized (this) {
            environment = env.clone();
        }
        if (values != null) {
            for (int i = 0; i < names.length; i++) {
                String name = names[i];
                Construct value;
                try {
                    value = values[i];
                } catch (Exception e) {
                    value = defaults[i].clone();
                }
                environment.getEnv(GlobalEnv.class).GetVarList().set(new IVariable(types[i], name, value, getTarget()));
            }
        }
        boolean hasArgumentsParam = false;
        for (String pName : this.names) {
            if (pName.equals("@arguments")) {
                hasArgumentsParam = true;
                break;
            }
        }
        if (!hasArgumentsParam) {
            CArray arguments = new CArray(node.getData().getTarget());
            if (values != null) {
                for (Construct value : values) {
                    arguments.push(value, node.getData().getTarget());
                }
            }
            environment.getEnv(GlobalEnv.class).GetVarList().set(new IVariable(CArray.TYPE, "@arguments", arguments, node.getData().getTarget()));
        }
        ParseTree newNode = new ParseTree(new CFunction("g", getTarget()), node.getFileOptions());
        List<ParseTree> children = new ArrayList<ParseTree>();
        children.add(node);
        newNode.setChildren(children);
        try {
            MethodScriptCompiler.execute(newNode, environment, null, environment.getEnv(GlobalEnv.class).GetScript());
        } catch (LoopManipulationException e) {
            // This shouldn't ever happen.
            LoopManipulationException lme = ((LoopManipulationException) e);
            Target t = lme.getTarget();
            ConfigRuntimeException.HandleUncaughtException(ConfigRuntimeException.CreateUncatchableException("A " + lme.getName() + "() bubbled up to the top of" + " a closure, which is unexpected behavior.", t), environment);
        } catch (FunctionReturnException ex) {
            // Check the return type of the closure to see if it matches the defined type
            // Normal execution.
            Construct ret = ex.getReturn();
            if (!InstanceofUtil.isInstanceof(ret, returnType)) {
                throw new CRECastException("Expected closure to return a value of type " + returnType.val() + " but a value of type " + ret.typeof() + " was returned instead", ret.getTarget());
            }
            // Now rethrow it
            throw ex;
        } catch (CancelCommandException e) {
        // die()
        } catch (ConfigRuntimeException ex) {
            if (ex instanceof AbstractCREException) {
                ((AbstractCREException) ex).freezeStackTraceElements(stManager);
            }
            throw ex;
        } catch (Throwable t) {
            // Not sure. Pop and re-throw.
            throw t;
        } finally {
            stManager.popStackTraceElement();
        }
        // If we got here, then there was no return type. This is fine, but only for returnType void or auto.
        if (!(returnType.equals(Auto.TYPE) || returnType.equals(CVoid.TYPE))) {
            throw new CRECastException("Expecting closure to return a value of type " + returnType.val() + "," + " but no value was returned.", node.getTarget());
        }
    } catch (CloneNotSupportedException ex) {
        Logger.getLogger(CClosure.class.getName()).log(Level.SEVERE, null, ex);
    }
}
Also used : ArrayList(java.util.ArrayList) ConfigRuntimeException(com.laytonsmith.core.exceptions.ConfigRuntimeException) CancelCommandException(com.laytonsmith.core.exceptions.CancelCommandException) AbstractCREException(com.laytonsmith.core.exceptions.CRE.AbstractCREException) CRECastException(com.laytonsmith.core.exceptions.CRE.CRECastException) StackTraceManager(com.laytonsmith.core.exceptions.StackTraceManager) CRECastException(com.laytonsmith.core.exceptions.CRE.CRECastException) LoopManipulationException(com.laytonsmith.core.exceptions.LoopManipulationException) ProgramFlowManipulationException(com.laytonsmith.core.exceptions.ProgramFlowManipulationException) AbstractCREException(com.laytonsmith.core.exceptions.CRE.AbstractCREException) ConfigRuntimeException(com.laytonsmith.core.exceptions.ConfigRuntimeException) CancelCommandException(com.laytonsmith.core.exceptions.CancelCommandException) FunctionReturnException(com.laytonsmith.core.exceptions.FunctionReturnException) Environment(com.laytonsmith.core.environments.Environment) GlobalEnv(com.laytonsmith.core.environments.GlobalEnv) FunctionReturnException(com.laytonsmith.core.exceptions.FunctionReturnException) LoopManipulationException(com.laytonsmith.core.exceptions.LoopManipulationException) ParseTree(com.laytonsmith.core.ParseTree)

Example 7 with CancelCommandException

use of com.laytonsmith.core.exceptions.CancelCommandException in project CommandHelper by EngineHub.

the class AbstractEvent method execute.

/**
 * This function is run when the actual event occurs.
 *
 * @param tree The compiled parse tree
 * @param b The bound event
 * @param env The operating environment
 * @param activeEvent The active event being executed
 */
@Override
public final void execute(ParseTree tree, BoundEvent b, Environment env, BoundEvent.ActiveEvent activeEvent) throws ConfigRuntimeException {
    preExecution(env, activeEvent);
    // Various events have a player to put into the env.
    // Do this after preExcecution() in case the particular event needs to inject the player first.
    Construct c = activeEvent.getParsedEvent().get("player");
    if (c != null) {
        try {
            MCPlayer p = Static.GetPlayer(c, Target.UNKNOWN);
            env.getEnv(CommandHelperEnvironment.class).SetPlayer(p);
        } catch (CREPlayerOfflineException e) {
            // Set env CommandSender to prevent incorrect inherited player from being used in a player event.
            if (env.getEnv(CommandHelperEnvironment.class).GetPlayer() != null) {
                env.getEnv(CommandHelperEnvironment.class).SetCommandSender(Static.getServer().getConsole());
            }
        }
    }
    ProfilePoint event = null;
    if (env.getEnv(GlobalEnv.class).GetProfiler() != null) {
        event = env.getEnv(GlobalEnv.class).GetProfiler().start("Event " + b.getEventName() + " (defined at " + b.getTarget().toString() + ")", LogLevel.ERROR);
    }
    try {
        try {
            // Get the label from the bind time environment, and put it in the current environment.
            String label = b.getEnvironment().getEnv(GlobalEnv.class).GetLabel();
            if (label == null) {
                // Set the permission to global if it's null, since that means
                // it wasn't set, and so we aren't in a secured environment anyways.
                label = Static.GLOBAL_PERMISSION;
            }
            env.getEnv(GlobalEnv.class).SetLabel(label);
            MethodScriptCompiler.execute(tree, env, null, null);
        } catch (CancelCommandException ex) {
            if (ex.getMessage() != null && !ex.getMessage().isEmpty()) {
                StreamUtils.GetSystemOut().println(ex.getMessage());
            }
        } catch (FunctionReturnException ex) {
        // We simply allow this to end the event execution
        } catch (ProgramFlowManipulationException ex) {
            ConfigRuntimeException.HandleUncaughtException(new CREFormatException("Unexpected control flow operation used.", ex.getTarget()), env);
        }
    } finally {
        if (event != null) {
            event.stop();
        }
        // Finally, among other things, we need to clean-up injected players and entities
        postExecution(env, activeEvent);
    }
}
Also used : CREPlayerOfflineException(com.laytonsmith.core.exceptions.CRE.CREPlayerOfflineException) CancelCommandException(com.laytonsmith.core.exceptions.CancelCommandException) MCPlayer(com.laytonsmith.abstraction.MCPlayer) Construct(com.laytonsmith.core.constructs.Construct) CommandHelperEnvironment(com.laytonsmith.core.environments.CommandHelperEnvironment) ProgramFlowManipulationException(com.laytonsmith.core.exceptions.ProgramFlowManipulationException) GlobalEnv(com.laytonsmith.core.environments.GlobalEnv) FunctionReturnException(com.laytonsmith.core.exceptions.FunctionReturnException) CREFormatException(com.laytonsmith.core.exceptions.CRE.CREFormatException) ProfilePoint(com.laytonsmith.core.profiler.ProfilePoint)

Example 8 with CancelCommandException

use of com.laytonsmith.core.exceptions.CancelCommandException in project CommandHelper by EngineHub.

the class MethodScriptExecutionQueue method getExceptionHandler.

private Thread.UncaughtExceptionHandler getExceptionHandler() {
    Thread.UncaughtExceptionHandler uceh = new Thread.UncaughtExceptionHandler() {

        @Override
        public void uncaughtException(Thread t, Throwable e) {
            Environment env = Environment.createEnvironment(MethodScriptExecutionQueue.this.env);
            if (e instanceof ConfigRuntimeException) {
                // This should be handled by the default UEH
                ConfigRuntimeException.HandleUncaughtException(((ConfigRuntimeException) e), env);
            } else if (e instanceof FunctionReturnException) {
                // ignored, so we want to warn them, but not trigger a flat out error.
                if (!(((FunctionReturnException) e).getReturn() instanceof CVoid)) {
                    ConfigRuntimeException.DoWarning("Closure is returning a value in an execution queue task," + " which is unexpected behavior. It may return void however, which will" + " simply stop that one task. " + ((FunctionReturnException) e).getTarget().toString());
                }
            } else if (e instanceof CancelCommandException) {
                // Ok. If there's a message, echo it to console.
                String msg = ((CancelCommandException) e).getMessage().trim();
                if (!"".equals(msg)) {
                    Target tt = ((CancelCommandException) e).getTarget();
                    new Echoes.console().exec(tt, env, new CString(msg, tt));
                }
            } else {
                // handle, so let it bubble up further.
                throw new RuntimeException(e);
            }
        }
    };
    return uceh;
}
Also used : ConfigRuntimeException(com.laytonsmith.core.exceptions.ConfigRuntimeException) CString(com.laytonsmith.core.constructs.CString) CVoid(com.laytonsmith.core.constructs.CVoid) CString(com.laytonsmith.core.constructs.CString) Echoes(com.laytonsmith.core.functions.Echoes) Target(com.laytonsmith.core.constructs.Target) ConfigRuntimeException(com.laytonsmith.core.exceptions.ConfigRuntimeException) CancelCommandException(com.laytonsmith.core.exceptions.CancelCommandException) Environment(com.laytonsmith.core.environments.Environment) FunctionReturnException(com.laytonsmith.core.exceptions.FunctionReturnException)

Aggregations

CancelCommandException (com.laytonsmith.core.exceptions.CancelCommandException)8 GlobalEnv (com.laytonsmith.core.environments.GlobalEnv)7 ConfigRuntimeException (com.laytonsmith.core.exceptions.ConfigRuntimeException)7 FunctionReturnException (com.laytonsmith.core.exceptions.FunctionReturnException)6 Environment (com.laytonsmith.core.environments.Environment)5 ParseTree (com.laytonsmith.core.ParseTree)4 CString (com.laytonsmith.core.constructs.CString)4 CommandHelperEnvironment (com.laytonsmith.core.environments.CommandHelperEnvironment)4 ProgramFlowManipulationException (com.laytonsmith.core.exceptions.ProgramFlowManipulationException)4 ArrayList (java.util.ArrayList)4 Construct (com.laytonsmith.core.constructs.Construct)3 IVariable (com.laytonsmith.core.constructs.IVariable)3 AbstractCREException (com.laytonsmith.core.exceptions.CRE.AbstractCREException)3 CRECastException (com.laytonsmith.core.exceptions.CRE.CRECastException)3 StackTraceManager (com.laytonsmith.core.exceptions.StackTraceManager)3 ProfilePoint (com.laytonsmith.core.profiler.ProfilePoint)3 MethodScriptComplete (com.laytonsmith.core.MethodScriptComplete)2 TokenStream (com.laytonsmith.core.compiler.TokenStream)2 CArray (com.laytonsmith.core.constructs.CArray)2 CVoid (com.laytonsmith.core.constructs.CVoid)2