如何在tkinter.Tcl().eval()中捕获自定义TclError错误信息
如何捕获tkinter.Tcl抛出的TclError中的自定义错误信息?
我使用Python 3.9.15版本,通过tkinter.Tcl实现了一个简易Tcl解析器,解析功能正常,但在实现解析失败处理逻辑时,无法获取抛出的TclError中包含的自定义错误信息。
解析器代码
import tkinter as tk from tkinter import Tcl def default_command_func(*args): print(f'default_command_func : {args}') return 'success' class TclParser(object): def __init__(self, data_cls) -> None: self.interp = tk.Tcl() self.data_cls = data_cls self.commands = {} def register_tcl_command(self, command_name, command_func): self.commands[command_name] = command_func def register_tcl_command_impl(self, command_name, command_func, data_base): def wrapper(*args): return command_func(data_base, args) self.interp.createcommand(command_name, wrapper) def parse_tcl(self, tcl_path): with open(tcl_path, 'r') as file: tcl_file = file.read() data_base = self.data_cls() for command_name, command_func in self.commands.items(): self.register_tcl_command_impl(command_name, command_func, data_base) try: self.interp.eval(tcl_file) except tk.TclError as e: print(f'unknow error : {str(e)}') return data_base
测试代码
def wrapped_cmd(data_base, args): if "error" in args: raise tk.TclError("Custom error: Invalid arguments passed") else: print(f"Executing custom command with args: {args}") return "success" tcl_script = """ custom_cmd arg1 arg2 custom_error error """ with open("test.tcl", "w") as f: f.write(tcl_script) parser = TclParser(int) parser.register_tcl_command('custom_cmd', wrapped_cmd) parser.register_tcl_command('custom_error', wrapped_cmd) tech = parser.parse_tcl("test.tcl")
当前输出
Executing custom command with args: ('arg1', 'arg2') unknow error :
期望输出
Executing custom command with args: ('arg1', 'arg2') parse tcl failed due to: Custom error: Invalid arguments passed unknow error : Custom error: Invalid arguments passed
解决方案
问题出在Python函数中直接抛出TclError时,Tcl解释器并未正确捕获并传递错误信息。需要在命令包装函数中主动调用Tcl解释器的error命令来设置错误状态,而非直接抛出Python异常。
修改代码
- 调整
register_tcl_command_impl中的包装函数,添加异常捕获并调用Tcl的error命令:
def register_tcl_command_impl(self, command_name, command_func, data_base): def wrapper(*args): try: return command_func(data_base, args) except tk.TclError as e: # 将自定义错误信息传递给Tcl解释器 self.interp.call('error', str(e)) self.interp.createcommand(command_name, wrapper)
- 优化
parse_tcl中的异常处理输出:
try: self.interp.eval(tcl_file) except tk.TclError as e: print(f'parse tcl failed due to: {str(e)}') print(f'unknow error : {str(e)}')
修改后输出
Executing custom command with args: ('arg1', 'arg2') parse tcl failed due to: Custom error: Invalid arguments passed unknow error : Custom error: Invalid arguments passed
原理说明
当在Python实现的Tcl命令中调用self.interp.call('error', msg)时,会触发Tcl解释器的错误机制,该错误会被上层的self.interp.eval()捕获并转换为tk.TclError异常,此时异常中就会包含自定义错误信息。直接抛出TclError无法关联到Tcl解释器的错误状态,导致信息丢失。
内容的提问来源于stack exchange,提问作者heixxxx
相关产品推荐
相关产品推荐

