mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2026-05-27 17:37:39 +08:00
Defer record_node_startup_error in prestartup error path; add docstrings
Some checks failed
Python Linting / Run Ruff (push) Has been cancelled
Python Linting / Run Pylint (push) Has been cancelled
Build package / Build Test (3.10) (push) Has been cancelled
Build package / Build Test (3.11) (push) Has been cancelled
Build package / Build Test (3.12) (push) Has been cancelled
Build package / Build Test (3.13) (push) Has been cancelled
Build package / Build Test (3.14) (push) Has been cancelled
Some checks failed
Python Linting / Run Ruff (push) Has been cancelled
Python Linting / Run Pylint (push) Has been cancelled
Build package / Build Test (3.10) (push) Has been cancelled
Build package / Build Test (3.11) (push) Has been cancelled
Build package / Build Test (3.12) (push) Has been cancelled
Build package / Build Test (3.13) (push) Has been cancelled
Build package / Build Test (3.14) (push) Has been cancelled
Buffer prestartup failures into a module-level list inside main.py instead of importing 'nodes' (and therefore 'torch') from within the exception handler. After the normal 'import nodes' line, drain the buffer via nodes.record_node_startup_error so bootstrap order stays deterministic regardless of whether a prestartup script succeeded. Also convert the explanatory '#' comment on the new /node_startup_errors endpoint into a proper docstring and add a docstring to execute_prestartup_script, addressing CodeRabbit's docstring-coverage warning on this PR. Addresses review feedback on PR #13184. Amp-Thread-ID: https://ampcode.com/threads/T-019e2f90-26fe-7048-9855-5ff39d08a3e0 Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
parent
ae539cfa0a
commit
7259e664ef
40
main.py
40
main.py
@ -136,7 +136,20 @@ def apply_custom_paths():
|
|||||||
folder_paths.set_user_directory(user_dir)
|
folder_paths.set_user_directory(user_dir)
|
||||||
|
|
||||||
|
|
||||||
|
# Buffer for prestartup failures. Recorded into `nodes.NODE_STARTUP_ERRORS`
|
||||||
|
# only AFTER the normal `import nodes` line below, so a failing prestartup
|
||||||
|
# script never triggers an early `import nodes` (and therefore `import torch`)
|
||||||
|
# on the error path.
|
||||||
|
_PRESTARTUP_FAILURES: list[dict] = []
|
||||||
|
|
||||||
|
|
||||||
def execute_prestartup_script():
|
def execute_prestartup_script():
|
||||||
|
"""Run every custom_nodes/*/prestartup_script.py once, before importing nodes.
|
||||||
|
|
||||||
|
Failures are buffered into the module-level ``_PRESTARTUP_FAILURES`` list and
|
||||||
|
must be flushed via ``record_node_startup_error`` after ``import nodes`` has
|
||||||
|
happened at its normal bootstrap point.
|
||||||
|
"""
|
||||||
if args.disable_all_custom_nodes and len(args.whitelist_custom_nodes) == 0:
|
if args.disable_all_custom_nodes and len(args.whitelist_custom_nodes) == 0:
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -149,14 +162,15 @@ def execute_prestartup_script():
|
|||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error(f"Failed to execute startup-script: {script_path} / {e}")
|
logging.error(f"Failed to execute startup-script: {script_path} / {e}")
|
||||||
from nodes import record_node_startup_error
|
# Buffer the failure - do NOT `import nodes` here, that would drag
|
||||||
record_node_startup_error(
|
# torch in before the intended bootstrap point.
|
||||||
module_path=os.path.dirname(script_path),
|
_PRESTARTUP_FAILURES.append({
|
||||||
source="custom_nodes",
|
"module_path": os.path.dirname(script_path),
|
||||||
phase="prestartup",
|
"source": "custom_nodes",
|
||||||
error=e,
|
"phase": "prestartup",
|
||||||
tb=traceback.format_exc(),
|
"error": e,
|
||||||
)
|
"tb": traceback.format_exc(),
|
||||||
|
})
|
||||||
return False
|
return False
|
||||||
|
|
||||||
node_paths = folder_paths.get_folder_paths("custom_nodes")
|
node_paths = folder_paths.get_folder_paths("custom_nodes")
|
||||||
@ -216,6 +230,16 @@ import execution
|
|||||||
import server
|
import server
|
||||||
from protocol import BinaryEventTypes
|
from protocol import BinaryEventTypes
|
||||||
import nodes
|
import nodes
|
||||||
|
|
||||||
|
# Flush any prestartup failures that were buffered before `nodes` was
|
||||||
|
# importable. Doing this here (rather than from the prestartup error
|
||||||
|
# handler) keeps the bootstrap order deterministic: `nodes` (and torch)
|
||||||
|
# import at this single line whether prestartup succeeded or failed.
|
||||||
|
if _PRESTARTUP_FAILURES:
|
||||||
|
for _failure in _PRESTARTUP_FAILURES:
|
||||||
|
nodes.record_node_startup_error(**_failure)
|
||||||
|
_PRESTARTUP_FAILURES.clear()
|
||||||
|
|
||||||
import comfy.model_management
|
import comfy.model_management
|
||||||
import comfyui_version
|
import comfyui_version
|
||||||
import app.logger
|
import app.logger
|
||||||
|
|||||||
25
server.py
25
server.py
@ -767,17 +767,20 @@ class PromptServer():
|
|||||||
|
|
||||||
@routes.get("/node_startup_errors")
|
@routes.get("/node_startup_errors")
|
||||||
async def get_node_startup_errors(request):
|
async def get_node_startup_errors(request):
|
||||||
# Group errors by source so the frontend/Manager can render them
|
"""Return startup errors recorded during node loading, grouped by source.
|
||||||
# in distinct sections. `source` is the same string as the
|
|
||||||
# module_parent used at load time (e.g. "custom_nodes",
|
Group errors by source so the frontend/Manager can render them in
|
||||||
# "comfy_extras", "comfy_api_nodes") and is left as a free-form
|
distinct sections. ``source`` is the same string as the
|
||||||
# string so the contract survives node-source layouts evolving.
|
``module_parent`` used at load time (e.g. ``"custom_nodes"``,
|
||||||
# The response only contains source buckets that actually had a
|
``"comfy_extras"``, ``"comfy_api_nodes"``) and is left as a
|
||||||
# failure; consumers should not assume any particular set of keys
|
free-form string so the contract survives node-source layouts
|
||||||
# is always present.
|
evolving. The response only contains source buckets that actually
|
||||||
#
|
had a failure; consumers should not assume any particular set of
|
||||||
# `module_path` is stripped because the absolute on-disk path is
|
keys is always present.
|
||||||
# internal detail that the frontend has no use for.
|
|
||||||
|
``module_path`` is stripped because the absolute on-disk path is
|
||||||
|
internal detail that the frontend has no use for.
|
||||||
|
"""
|
||||||
grouped: dict[str, dict[str, dict]] = {}
|
grouped: dict[str, dict[str, dict]] = {}
|
||||||
for entry in nodes.NODE_STARTUP_ERRORS.values():
|
for entry in nodes.NODE_STARTUP_ERRORS.values():
|
||||||
source = entry.get("source", "custom_nodes")
|
source = entry.get("source", "custom_nodes")
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user