Skip to content

Commit d94e072

Browse files
Handle HTML fallbacks for node help and skip blueprint docs (#7021)
explicitly prevents subgraphs from making an api call since they don't have docs, this was previously reliant on a non-ok resolution also doesn't try returning anything that has contenttype of text/html to prevent the markdown renderer from crashing ## Summary - short-circuit blueprint/subgraph nodes in help: skip doc fetch and return the node description, avoiding SPA fallback responses - guard node help fetch against HTML/SPA fallbacks using content-type checks; treat them as missing and trigger the existing description fallback - keep base URL logic unchanged for non-blueprint nodes ## Testing - pnpm typecheck - pnpm lint:fix - pnpm test:unit
1 parent fe47a48 commit d94e072

File tree

2 files changed

+42
-14
lines changed

2 files changed

+42
-14
lines changed

src/services/nodeHelpService.ts

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ class NodeHelpService {
77
async fetchNodeHelp(node: ComfyNodeDefImpl, locale: string): Promise<string> {
88
const nodeSource = getNodeSource(node.python_module)
99

10+
if (nodeSource.type === NodeSourceType.Blueprint) {
11+
return node.description || ''
12+
}
13+
1014
if (nodeSource.type === NodeSourceType.CustomNodes) {
1115
return this.fetchCustomNodeHelp(node, locale)
1216
} else {
@@ -19,39 +23,60 @@ class NodeHelpService {
1923
locale: string
2024
): Promise<string> {
2125
const customNodeName = extractCustomNodeName(node.python_module)
26+
let lastError: string | undefined
2227
if (!customNodeName) {
2328
throw new Error('Invalid custom node module')
2429
}
2530

2631
// Try locale-specific path first
2732
const localePath = `/extensions/${customNodeName}/docs/${node.name}/${locale}.md`
28-
let res = await fetch(api.fileURL(localePath))
33+
const localeDoc = await this.tryFetchMarkdown(localePath)
34+
if (localeDoc.text) return localeDoc.text
35+
lastError = localeDoc.errorText
2936

30-
if (!res.ok) {
31-
// Fall back to non-locale path
32-
const fallbackPath = `/extensions/${customNodeName}/docs/${node.name}.md`
33-
res = await fetch(api.fileURL(fallbackPath))
34-
}
35-
36-
if (!res.ok) {
37-
throw new Error(res.statusText)
38-
}
37+
// Fall back to non-locale path
38+
const fallbackPath = `/extensions/${customNodeName}/docs/${node.name}.md`
39+
const fallbackDoc = await this.tryFetchMarkdown(fallbackPath)
40+
if (fallbackDoc.text) return fallbackDoc.text
41+
lastError = fallbackDoc.errorText ?? lastError
3942

40-
return res.text()
43+
throw new Error(lastError ?? 'Help not found')
4144
}
4245

4346
private async fetchCoreNodeHelp(
4447
node: ComfyNodeDefImpl,
4548
locale: string
4649
): Promise<string> {
4750
const mdUrl = `/docs/${node.name}/${locale}.md`
48-
const res = await fetch(api.fileURL(mdUrl))
51+
const doc = await this.tryFetchMarkdown(mdUrl)
52+
if (!doc.text) {
53+
throw new Error(doc.errorText ?? 'Help not found')
54+
}
55+
56+
return doc.text
57+
}
58+
59+
/**
60+
* Fetch a markdown file and return its text, guarding against HTML/SPA fallbacks.
61+
* Returns null when not OK or when the content type indicates HTML.
62+
*/
63+
private async tryFetchMarkdown(
64+
path: string
65+
): Promise<{ text: string | null; errorText?: string }> {
66+
const res = await fetch(api.fileURL(path))
4967

5068
if (!res.ok) {
51-
throw new Error(res.statusText)
69+
return { text: null, errorText: res.statusText }
5270
}
5371

54-
return res.text()
72+
const contentType = res.headers?.get?.('content-type') ?? ''
73+
const text = await res.text()
74+
75+
const isHtmlContentType = contentType.includes('text/html')
76+
77+
if (isHtmlContentType) return { text: null, errorText: res.statusText }
78+
79+
return { text }
5580
}
5681
}
5782

src/workbench/utils/nodeHelpUtil.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ export function extractCustomNodeName(
1515

1616
export function getNodeHelpBaseUrl(node: ComfyNodeDefImpl): string {
1717
const nodeSource = getNodeSource(node.python_module)
18+
if (nodeSource.type === NodeSourceType.Blueprint) {
19+
return ''
20+
}
1821
if (nodeSource.type === NodeSourceType.CustomNodes) {
1922
const customNodeName = extractCustomNodeName(node.python_module)
2023
if (customNodeName) {

0 commit comments

Comments
 (0)