Thu, 03 Sep 2015 21:47:48 +0530
8087292: nashorn should have a "fail-fast" option for scripting, analog to bash "set -e"
Reviewed-by: hannesw, jlaskey, mhaupt
1.1 --- a/src/jdk/nashorn/internal/objects/Global.java Fri Sep 04 17:17:44 2015 +0530 1.2 +++ b/src/jdk/nashorn/internal/objects/Global.java Thu Sep 03 21:47:48 2015 +0530 1.3 @@ -2420,7 +2420,7 @@ 1.4 } 1.5 1.6 private void initScripting(final ScriptEnvironment scriptEnv) { 1.7 - Object value; 1.8 + ScriptObject value; 1.9 value = ScriptFunctionImpl.makeFunction("readLine", ScriptingFunctions.READLINE); 1.10 addOwnProperty("readLine", Attribute.NOT_ENUMERABLE, value); 1.11 1.12 @@ -2429,11 +2429,13 @@ 1.13 1.14 final String execName = ScriptingFunctions.EXEC_NAME; 1.15 value = ScriptFunctionImpl.makeFunction(execName, ScriptingFunctions.EXEC); 1.16 + value.addOwnProperty(ScriptingFunctions.THROW_ON_ERROR_NAME, Attribute.NOT_ENUMERABLE, false); 1.17 + 1.18 addOwnProperty(execName, Attribute.NOT_ENUMERABLE, value); 1.19 1.20 // Nashorn extension: global.echo (scripting-mode-only) 1.21 // alias for "print" 1.22 - value = get("print"); 1.23 + value = (ScriptObject)get("print"); 1.24 addOwnProperty("echo", Attribute.NOT_ENUMERABLE, value); 1.25 1.26 // Nashorn extension: global.$OPTIONS (scripting-mode-only)
2.1 --- a/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java Fri Sep 04 17:17:44 2015 +0530 2.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java Thu Sep 03 21:47:48 2015 +0530 2.3 @@ -26,6 +26,7 @@ 2.4 package jdk.nashorn.internal.runtime; 2.5 2.6 import static jdk.nashorn.internal.lookup.Lookup.MH; 2.7 +import static jdk.nashorn.internal.runtime.ECMAErrors.rangeError; 2.8 import static jdk.nashorn.internal.runtime.ECMAErrors.typeError; 2.9 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; 2.10 2.11 @@ -70,6 +71,9 @@ 2.12 /** EXIT name - special property used by $EXEC API. */ 2.13 public static final String EXIT_NAME = "$EXIT"; 2.14 2.15 + /** THROW_ON_ERROR name - special property of the $EXEC function used by $EXEC API. */ 2.16 + public static final String THROW_ON_ERROR_NAME = "throwOnError"; 2.17 + 2.18 /** Names of special properties used by $ENV API. */ 2.19 public static final String ENV_NAME = "$ENV"; 2.20 2.21 @@ -244,6 +248,19 @@ 2.22 } 2.23 } 2.24 2.25 + // if we got a non-zero exit code ("failure"), then we have to decide to throw error or not 2.26 + if (exit != 0) { 2.27 + // get the $EXEC function object from the global object 2.28 + final Object exec = global.get(EXEC_NAME); 2.29 + assert exec instanceof ScriptObject : EXEC_NAME + " is not a script object!"; 2.30 + 2.31 + // Check if the user has set $EXEC.throwOnError property to true. If so, throw RangeError 2.32 + // If that property is not set or set to false, then silently proceed with the rest. 2.33 + if (JSType.toBoolean(((ScriptObject)exec).get(THROW_ON_ERROR_NAME))) { 2.34 + throw rangeError("exec.returned.non.zero", ScriptRuntime.safeToString(exit)); 2.35 + } 2.36 + } 2.37 + 2.38 // Return the result from stdout. 2.39 return out; 2.40 }
3.1 --- a/src/jdk/nashorn/internal/runtime/resources/Messages.properties Fri Sep 04 17:17:44 2015 +0530 3.2 +++ b/src/jdk/nashorn/internal/runtime/resources/Messages.properties Thu Sep 03 21:47:48 2015 +0530 3.3 @@ -163,6 +163,7 @@ 3.4 range.error.invalid.date=Invalid Date 3.5 range.error.too.many.errors=Script contains too many errors: {0} errors 3.6 range.error.concat.string.too.big=Concatenated String is too big 3.7 +range.error.exec.returned.non.zero=$EXEC returned non-zero exit code: {0} 3.8 3.9 reference.error.not.defined="{0}" is not defined 3.10 reference.error.cant.be.used.as.lhs="{0}" can not be used as the left-hand side of assignment
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/test/script/trusted/JDK-8087292.js Thu Sep 03 21:47:48 2015 +0530 4.3 @@ -0,0 +1,54 @@ 4.4 +/* 4.5 + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 4.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.7 + * 4.8 + * This code is free software; you can redistribute it and/or modify it 4.9 + * under the terms of the GNU General Public License version 2 only, as 4.10 + * published by the Free Software Foundation. 4.11 + * 4.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 4.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 4.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 4.15 + * version 2 for more details (a copy is included in the LICENSE file that 4.16 + * accompanied this code). 4.17 + * 4.18 + * You should have received a copy of the GNU General Public License version 4.19 + * 2 along with this work; if not, write to the Free Software Foundation, 4.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 4.21 + * 4.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 4.23 + * or visit www.oracle.com if you need additional information or have any 4.24 + * questions. 4.25 + */ 4.26 + 4.27 +/** 4.28 + * JDK-8087292: nashorn should have a "fail-fast" option for scripting, analog to bash "set -e" 4.29 + * 4.30 + * @test 4.31 + * @option -scripting 4.32 + * @run 4.33 + */ 4.34 + 4.35 +function tryExec() { 4.36 + try { 4.37 + `java` 4.38 + } catch (e) { 4.39 + print(e); 4.40 + } 4.41 + 4.42 + // make sure we got non-zero ("failure") exit code! 4.43 + if ($EXIT == 0) { 4.44 + print("Error: expected $EXIT code to be non-zero"); 4.45 + } 4.46 +} 4.47 + 4.48 +// no exception now! 4.49 +tryExec(); 4.50 + 4.51 +// turn on error with non-zero exit code 4.52 +$EXEC.throwOnError = true; 4.53 +tryExec(); 4.54 + 4.55 +// no exception after this 4.56 +$EXEC.throwOnError = false; 4.57 +tryExec();
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/test/script/trusted/JDK-8087292.js.EXPECTED Thu Sep 03 21:47:48 2015 +0530 5.3 @@ -0,0 +1,1 @@ 5.4 +RangeError: $EXEC returned non-zero exit code: 1