1+ import os
2+ import sys
3+ import builtins
4+
15import hmac
26import datetime
37import json
48import time
59import markupsafe
6- import os
710import re
811import subprocess
912import tempfile
4144from walkoff_app_sdk .app_base import AppBase
4245#from shuffle_sdk import AppBase
4346
47+ # Override exit(), sys.exit, and os._exit
48+ # sys.exit() can be caught, meaning we can have a custom handler for it
49+ builtins .exit = sys .exit
50+ os .exit = sys .exit
51+ os ._exit = sys .exit
52+
4453class Tools (AppBase ):
4554 __version__ = "1.2.0"
4655 app_name = (
@@ -573,7 +582,6 @@ def execute_python(self, code):
573582 "message" : f"Filename needs to contain .py" ,
574583 }
575584
576-
577585 # Write the code to a file
578586 # 1. Take the data into a file
579587 # 2. Subprocess execute file?
@@ -594,7 +602,27 @@ def custom_print(*args, **kwargs):
594602
595603 globals_copy ["self" ] = self
596604
597- exec (code , globals_copy )
605+ try :
606+ exec (code , globals_copy )
607+ except SystemExit as e :
608+ # Same as a return
609+ pass
610+ except SyntaxError as e :
611+ # Special handler for return usage. Makes return act as
612+ # an exit()
613+ if "'return' outside function" in str (e ):
614+ return {
615+ "success" : False ,
616+ "message" : f"Instead of using 'return' without a function, use 'exit()' to return when not inside a function. Raw Syntax error: { e } " ,
617+ }
618+ else :
619+ return {
620+ "success" : False ,
621+ "message" : f"Syntax Error: { e } " ,
622+ }
623+
624+ # this doesn't work to capture top-level returns
625+ # Reason: SyntaxError makes it crash BEFORE it reaches the return
598626
599627 s = f .getvalue ()
600628 f .close () # why: https://www.youtube.com/watch?v=6SA6S9Ca5-U
@@ -623,7 +651,7 @@ def custom_print(*args, **kwargs):
623651 except Exception as e :
624652 return {
625653 "success" : False ,
626- "message" : f"exception : { e } " ,
654+ "message" : f"Exception : { e } " ,
627655 }
628656
629657 def execute_bash (self , code , shuffle_input ):
0 commit comments