mirror of
https://github.com/nosqlbench/nosqlbench.git
synced 2025-02-25 18:55:28 -06:00
clarify scenario error handling logic
This commit is contained in:
parent
1fe38b4394
commit
452224a201
@ -0,0 +1,83 @@
|
||||
package io.nosqlbench.engine.core;
|
||||
|
||||
import io.nosqlbench.nb.api.errors.BasicError;
|
||||
import org.graalvm.polyglot.PolyglotException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.script.ScriptException;
|
||||
|
||||
/**
|
||||
* This class is meant to consolidate the error handling logic for the varios types of errors
|
||||
* that may bubble up from the layers within NoSQLBench. As a layered system, some of the included
|
||||
* libraries tend to layer the exceptions beyond a point of recognizability. The logic in this
|
||||
* class should do the following:
|
||||
*
|
||||
* <ol>
|
||||
* <li>Report an error in the most intelligible way to the user.</li>
|
||||
* </ol>
|
||||
*
|
||||
* That is all. When this error handler is invoked, it is a foregone conclusion that the scenario
|
||||
* is not able to continue, else the error would have been trapped and handled internal to a lower-level
|
||||
* class. It is the calling exception handler's responsibility to finally shut down the scenario
|
||||
* cleanly and return appropriately. Thus, <em>You should not throw errors from this class. You should only
|
||||
* unwrap and explain errors, sending contents to the logfile as appropriate.</em>
|
||||
*
|
||||
*/
|
||||
public class ScenarioErrorHandler {
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(ScenarioErrorHandler.class);
|
||||
|
||||
public static void handle(String script, Throwable t, boolean wantsStackTraces) {
|
||||
if (t instanceof ScriptException) {
|
||||
handleScriptException(script, (ScriptException) t, wantsStackTraces);
|
||||
} else if (t instanceof BasicError) {
|
||||
handleBasicError((BasicError) t, wantsStackTraces);
|
||||
} else if (t instanceof Exception){
|
||||
handleInternalError((Exception) t, wantsStackTraces);
|
||||
}
|
||||
}
|
||||
|
||||
private static void handleInternalError(Exception e, boolean wantsStackTraces) {
|
||||
String prefix = "internal error: ";
|
||||
if (!e.getCause().getClass().getCanonicalName().contains("io.nosqlbench")) {
|
||||
prefix = "Error from driver or included library: ";
|
||||
}
|
||||
|
||||
if (wantsStackTraces) {
|
||||
logger.error(prefix + e.getMessage(),e);
|
||||
} else {
|
||||
logger.error(e.getMessage());
|
||||
logger.error("for the full stack trace, run with --show-stacktraces");
|
||||
}
|
||||
}
|
||||
|
||||
private static void handleScriptException(String script, ScriptException e, boolean wantsStackTraces) {
|
||||
Throwable cause = e.getCause();
|
||||
if (cause instanceof PolyglotException) {
|
||||
Throwable hostException = ((PolyglotException) cause).asHostException();
|
||||
if (hostException instanceof BasicError) {
|
||||
handleBasicError((BasicError)hostException, wantsStackTraces);
|
||||
} else {
|
||||
handle(script,hostException, wantsStackTraces);
|
||||
}
|
||||
} else {
|
||||
if (wantsStackTraces) {
|
||||
logger.error("Unknown script exception:",e);
|
||||
} else {
|
||||
logger.error(e.getMessage());
|
||||
logger.error("for the full stack trace, run with --show-stacktraces");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void handleBasicError(BasicError e, boolean wantsStackTraces) {
|
||||
if (wantsStackTraces) {
|
||||
logger.error(e.getMessage(),e);
|
||||
} else {
|
||||
logger.error(e.getMessage());
|
||||
logger.error("for the full stack trace, run with --show-stacktraces");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -19,16 +19,12 @@ import com.codahale.metrics.MetricRegistry;
|
||||
import com.oracle.truffle.js.scriptengine.GraalJSScriptEngine;
|
||||
import io.nosqlbench.engine.core.*;
|
||||
import io.nosqlbench.engine.core.metrics.PolyglotMetricRegistryBindings;
|
||||
import io.nosqlbench.nb.api.errors.BasicError;
|
||||
import io.nosqlbench.engine.api.extensions.ScriptingPluginInfo;
|
||||
import io.nosqlbench.engine.api.metrics.ActivityMetrics;
|
||||
import io.nosqlbench.engine.core.metrics.NashornMetricRegistryBindings;
|
||||
import io.nosqlbench.engine.api.scripting.ScriptEnvBuffer;
|
||||
import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
|
||||
import org.graalvm.polyglot.Context;
|
||||
import org.graalvm.polyglot.EnvironmentAccess;
|
||||
import org.graalvm.polyglot.HostAccess;
|
||||
import org.graalvm.polyglot.PolyglotAccess;
|
||||
import org.graalvm.polyglot.*;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.script.*;
|
||||
@ -61,17 +57,19 @@ public class Scenario implements Callable<ScenarioResult> {
|
||||
private ScenarioLogger scenarioLogger;
|
||||
private ScriptParams scenarioScriptParams;
|
||||
private Engine engine = Engine.Graalvm;
|
||||
private boolean wantsStackTraces=false;
|
||||
|
||||
public enum Engine {
|
||||
Nashorn,
|
||||
Graalvm
|
||||
}
|
||||
|
||||
public Scenario(String name, Engine engine, String progressInterval, boolean wantsGraaljsCompatMode) {
|
||||
public Scenario(String name, Engine engine, String progressInterval, boolean wantsGraaljsCompatMode, boolean wantsStackTraces) {
|
||||
this.name = name;
|
||||
this.engine = engine;
|
||||
this.progressInterval = progressInterval;
|
||||
this.wantsGraaljsCompatMode = wantsGraaljsCompatMode;
|
||||
this.wantsStackTraces = wantsStackTraces;
|
||||
}
|
||||
|
||||
public Scenario(String name, Engine engine) {
|
||||
@ -218,28 +216,10 @@ public class Scenario implements Callable<ScenarioResult> {
|
||||
}
|
||||
System.err.flush();
|
||||
System.out.flush();
|
||||
} catch (ScriptException e) {
|
||||
String diagname = "diag_" + System.currentTimeMillis() + ".js";
|
||||
try {
|
||||
Path diagFilePath = Paths.get(scenarioLogger.getLogDir(), diagname);
|
||||
Files.writeString(diagFilePath, script);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
String errorDesc = "Script error while running scenario:" + e.toString() + ", script content is at " + diagname;
|
||||
e.printStackTrace();
|
||||
logger.error(errorDesc, e);
|
||||
scenarioController.forceStopScenario(5000);
|
||||
throw new RuntimeException("Script error while running scenario:" + e.getMessage(), e);
|
||||
} catch (BasicError ue) {
|
||||
logger.error(ue.getMessage());
|
||||
scenarioController.forceStopScenario(5000);
|
||||
throw ue;
|
||||
} catch (Exception o) {
|
||||
String errorDesc = "Non-Script error while running scenario:" + o.getMessage();
|
||||
logger.error(errorDesc, o);
|
||||
scenarioController.forceStopScenario(5000);
|
||||
throw new RuntimeException("Non-Script error while running scenario:" + o.getMessage(), o);
|
||||
} catch (Exception e) {
|
||||
ScenarioErrorHandler.handle(script,e,wantsStackTraces);
|
||||
} finally {
|
||||
scenarioController.forceStopScenario(5000);
|
||||
System.out.flush();
|
||||
System.err.flush();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user