Skip to content

Commit

Permalink
ScriptProfile: Recover from closed context for JS Scripting (#4437)
Browse files Browse the repository at this point in the history
Co-authored-by: J-N-K <[email protected]>
Signed-off-by: Florian Hotze <[email protected]>
  • Loading branch information
florian-h05 and J-N-K authored Nov 6, 2024
1 parent a31e837 commit 4eec4a3
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,18 @@ public void deactivate() {
return result == null ? null : result.toString();
} catch (ScriptException e) {
throw new TransformationException("Failed to execute script.", e);
} catch (IllegalStateException e) {
// ISE thrown by JS Scripting if script engine already closed
if ("The Context is already closed.".equals(e.getMessage())) {
logger.warn(
"Script engine context {} is already closed, this should not happen. Recreating script engine.",
scriptUid);
scriptCache.remove(scriptUid);
return transform(function, source);
} else {
// rethrow
throw e;
}
}
} finally {
scriptRecord.lock.unlock();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;
import org.openhab.core.config.core.ConfigDescriptionRegistry;
import org.openhab.core.test.java.JavaTest;
import org.openhab.core.transform.Transformation;
import org.openhab.core.transform.TransformationException;
import org.openhab.core.transform.TransformationRegistry;
Expand All @@ -49,7 +50,7 @@
@NonNullByDefault
@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
public class ScriptTransformationServiceTest {
public class ScriptTransformationServiceTest extends JavaTest {
private static final String SCRIPT_LANGUAGE = "customDsl";
private static final String SCRIPT_UID = "scriptUid." + SCRIPT_LANGUAGE;
private static final String INVALID_SCRIPT_UID = "invalidScriptUid";
Expand Down Expand Up @@ -189,6 +190,21 @@ public void scriptExceptionResultsInTransformationException() throws ScriptExcep
assertThat(e.getCause().getMessage(), is("exception"));
}

@Test
public void recoversFromClosedScriptContext() throws ScriptException, TransformationException {
when(scriptEngine.eval(SCRIPT)).thenThrow(new IllegalStateException("The Context is already closed."))
.thenReturn(SCRIPT_OUTPUT);
setupInterceptedLogger(ScriptTransformationService.class, LogLevel.WARN);

String returnValue = Objects.requireNonNull(service.transform(SCRIPT_UID, "input"));

assertThat(returnValue, is(SCRIPT_OUTPUT));

stopInterceptedLogger(ScriptTransformationService.class);
assertLogMessage(ScriptTransformationService.class, LogLevel.WARN, "Script engine context " + SCRIPT_UID
+ " is already closed, this should not happen. Recreating script engine.");
}

@Test
public void inlineScriptProperlyProcessed() throws TransformationException, ScriptException {
service.transform(INLINE_SCRIPT, "input");
Expand Down

0 comments on commit 4eec4a3

Please sign in to comment.