Merge pull request #114

* Better exception handling / error reporting for add job screen

* Don't supress exceptions for potentially long running functions in bl…

* Increase Blender pack_project_file timeout to 120s
This commit is contained in:
2024-08-20 15:20:24 -05:00
committed by GitHub
parent 751d74ced3
commit e792698480
2 changed files with 83 additions and 62 deletions

View File

@@ -55,7 +55,9 @@ class Blender(BaseRenderEngine):
return subprocess.run([self.renderer_path(), '-b', project_path, '--python-expr', python_expression], return subprocess.run([self.renderer_path(), '-b', project_path, '--python-expr', python_expression],
capture_output=True, timeout=timeout, creationflags=_creationflags) capture_output=True, timeout=timeout, creationflags=_creationflags)
except Exception as e: except Exception as e:
logger.error(f"Error running python expression in blender: {e}") err_msg = f"Error running python expression in blender: {e}"
logger.error(err_msg)
raise ChildProcessError(err_msg)
else: else:
raise FileNotFoundError(f'Project file not found: {project_path}') raise FileNotFoundError(f'Project file not found: {project_path}')
@@ -70,9 +72,16 @@ class Blender(BaseRenderEngine):
command = [self.renderer_path(), '-b', '--python', script_path] command = [self.renderer_path(), '-b', '--python', script_path]
if project_path: if project_path:
command.insert(2, project_path) command.insert(2, project_path)
return subprocess.run(command, capture_output=True, timeout=timeout, creationflags=_creationflags) result = subprocess.run(command, capture_output=True, timeout=timeout, creationflags=_creationflags)
return result
except subprocess.TimeoutExpired:
err_msg = f"Timed out after {timeout}s while running python script in blender: {script_path}"
logger.error(err_msg)
raise TimeoutError(err_msg)
except Exception as e: except Exception as e:
logger.exception(f"Error running python script in blender: {e}") err_msg = f"Error running python script in blender: {e}"
logger.error(err_msg)
raise ChildProcessError(err_msg)
def get_project_info(self, project_path, timeout=10): def get_project_info(self, project_path, timeout=10):
scene_info = {} scene_info = {}
@@ -89,10 +98,12 @@ class Blender(BaseRenderEngine):
elif line.startswith('Error'): elif line.startswith('Error'):
logger.error(f"get_scene_info error: {line.strip()}") logger.error(f"get_scene_info error: {line.strip()}")
except Exception as e: except Exception as e:
logger.error(f'Error getting file details for .blend file: {e}') msg = f'Error getting file details for .blend file: {e}'
logger.error(msg)
raise ChildProcessError(msg)
return scene_info return scene_info
def pack_project_file(self, project_path, timeout=30): def pack_project_file(self, project_path, timeout=None):
# Credit to L0Lock for pack script - https://blender.stackexchange.com/a/243935 # Credit to L0Lock for pack script - https://blender.stackexchange.com/a/243935
try: try:
logger.info(f"Starting to pack Blender file: {project_path}") logger.info(f"Starting to pack Blender file: {project_path}")
@@ -115,7 +126,9 @@ class Blender(BaseRenderEngine):
logger.info(f'Blender file packed successfully to {new_path}') logger.info(f'Blender file packed successfully to {new_path}')
return new_path return new_path
except Exception as e: except Exception as e:
logger.error(f'Error packing .blend file: {e}') msg = f'Error packing .blend file: {e}'
logger.error(msg)
raise ChildProcessError(msg)
return None return None
def get_arguments(self): def get_arguments(self):
@@ -172,7 +185,7 @@ class Blender(BaseRenderEngine):
return render_engines return render_engines
def perform_presubmission_tasks(self, project_path): def perform_presubmission_tasks(self, project_path):
packed_path = self.pack_project_file(project_path, timeout=30) packed_path = self.pack_project_file(project_path, timeout=120)
return packed_path return packed_path

View File

@@ -377,7 +377,7 @@ class NewRenderJobForm(QWidget):
self.cameras_group.setHidden(True) self.cameras_group.setHidden(True)
self.submit_button.setEnabled(enabled) self.submit_button.setEnabled(enabled)
def after_job_submission(self, result): def after_job_submission(self, error_string):
# UI cleanup # UI cleanup
self.submit_progress.setMaximum(0) self.submit_progress.setMaximum(0)
@@ -389,7 +389,7 @@ class NewRenderJobForm(QWidget):
self.toggle_renderer_enablement(True) self.toggle_renderer_enablement(True)
self.msg_box = QMessageBox() self.msg_box = QMessageBox()
if result.ok: if not error_string:
self.msg_box.setStandardButtons(QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No) self.msg_box.setStandardButtons(QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No)
self.msg_box.setIcon(QMessageBox.Icon.Information) self.msg_box.setIcon(QMessageBox.Icon.Information)
self.msg_box.setText("Job successfully submitted to server. Submit another?") self.msg_box.setText("Job successfully submitted to server. Submit another?")
@@ -400,7 +400,7 @@ class NewRenderJobForm(QWidget):
else: else:
self.msg_box.setStandardButtons(QMessageBox.StandardButton.Ok) self.msg_box.setStandardButtons(QMessageBox.StandardButton.Ok)
self.msg_box.setIcon(QMessageBox.Icon.Critical) self.msg_box.setIcon(QMessageBox.Icon.Critical)
self.msg_box.setText(result.text or "Unknown error") self.msg_box.setText(error_string)
self.msg_box.setWindowTitle("Error") self.msg_box.setWindowTitle("Error")
self.msg_box.exec() self.msg_box.exec()
@@ -431,7 +431,7 @@ class NewRenderJobForm(QWidget):
class SubmitWorker(QThread): class SubmitWorker(QThread):
"""Worker class called to submit all the jobs to the server and update the UI accordingly""" """Worker class called to submit all the jobs to the server and update the UI accordingly"""
message_signal = pyqtSignal(Response) message_signal = pyqtSignal(str)
update_ui_signal = pyqtSignal(str, str) update_ui_signal = pyqtSignal(str, str)
def __init__(self, window): def __init__(self, window):
@@ -447,6 +447,7 @@ class SubmitWorker(QThread):
self.update_ui_signal.emit(hostname, percent) self.update_ui_signal.emit(hostname, percent)
return callback return callback
try:
hostname = self.window.server_input.currentText() hostname = self.window.server_input.currentText()
job_json = {'owner': psutil.Process().username() + '@' + socket.gethostname(), job_json = {'owner': psutil.Process().username() + '@' + socket.gethostname(),
'renderer': self.window.renderer_type.currentText().lower(), 'renderer': self.window.renderer_type.currentText().lower(),
@@ -499,9 +500,16 @@ class SubmitWorker(QThread):
engine = EngineManager.engine_with_name(self.window.renderer_type.currentText().lower()) engine = EngineManager.engine_with_name(self.window.renderer_type.currentText().lower())
input_path = engine().perform_presubmission_tasks(input_path) input_path = engine().perform_presubmission_tasks(input_path)
# submit # submit
err_msg = ""
result = self.window.server_proxy.post_job_to_server(file_path=input_path, job_list=job_list, result = self.window.server_proxy.post_job_to_server(file_path=input_path, job_list=job_list,
callback=create_callback) callback=create_callback)
self.message_signal.emit(result) if not (result and result.ok):
err_msg = "Error posting job to server."
self.message_signal.emit(err_msg)
except Exception as e:
self.message_signal.emit(str(e))
class GetProjectInfoWorker(QThread): class GetProjectInfoWorker(QThread):