Fix 8 bugs from second code review
HIGH: - Fix JS TypeError on empty API response: validate keys/types are arrays before using them; add HTTP status check (resp.ok) - Fix BEGIN IMMEDIATE conflict: set isolation_level=None (autocommit) on SQLite connection so explicit transactions work without implicit ones MEDIUM: - Fix import_json_file non-atomic: wrap entire operation in BEGIN/COMMIT with ROLLBACK on error — no more partial imports - Fix crash on non-dict batch_data items: skip non-dict elements - Fix comma-in-key corruption: store keys/types as JSON arrays in hidden widgets instead of comma-delimited strings (backward-compat fallback) - Fix blocking I/O in API routes: change async def to def so FastAPI auto-threads the synchronous SQLite calls LOW: - Fix missing ?. on app.graph.setDirtyCanvas in refreshDynamicOutputs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -56,20 +56,27 @@ app.registerExtension({
|
||||
const resp = await api.fetchApi(
|
||||
`/json_manager/get_project_keys?url=${encodeURIComponent(urlWidget.value)}&project=${encodeURIComponent(projectWidget.value)}&file=${encodeURIComponent(fileWidget.value)}&seq=${seqWidget?.value || 1}`
|
||||
);
|
||||
const data = await resp.json();
|
||||
const { keys, types } = data;
|
||||
|
||||
// If the API returned an error, keep existing outputs and links intact
|
||||
if (data.error) {
|
||||
console.warn("[ProjectLoaderDynamic] API error, keeping existing outputs:", data.error);
|
||||
if (!resp.ok) {
|
||||
console.warn("[ProjectLoaderDynamic] HTTP error", resp.status, "— keeping existing outputs");
|
||||
return;
|
||||
}
|
||||
|
||||
// Store keys and types in hidden widgets for persistence
|
||||
const data = await resp.json();
|
||||
const keys = data.keys;
|
||||
const types = data.types;
|
||||
|
||||
// If the API returned an error or missing data, keep existing outputs and links intact
|
||||
if (data.error || !Array.isArray(keys) || !Array.isArray(types)) {
|
||||
console.warn("[ProjectLoaderDynamic] API error or missing data, keeping existing outputs:", data.error || "no keys/types");
|
||||
return;
|
||||
}
|
||||
|
||||
// Store keys and types in hidden widgets for persistence (JSON-encoded)
|
||||
const okWidget = this.widgets?.find(w => w.name === "output_keys");
|
||||
if (okWidget) okWidget.value = keys.join(",");
|
||||
if (okWidget) okWidget.value = JSON.stringify(keys);
|
||||
const otWidget = this.widgets?.find(w => w.name === "output_types");
|
||||
if (otWidget) otWidget.value = types.join(",");
|
||||
if (otWidget) otWidget.value = JSON.stringify(types);
|
||||
|
||||
// Build a map of current output names to slot indices
|
||||
const oldSlots = {};
|
||||
@@ -116,7 +123,7 @@ app.registerExtension({
|
||||
}
|
||||
|
||||
this.setSize(this.computeSize());
|
||||
app.graph.setDirtyCanvas(true, true);
|
||||
app.graph?.setDirtyCanvas(true, true);
|
||||
} catch (e) {
|
||||
console.error("[ProjectLoaderDynamic] Refresh failed:", e);
|
||||
}
|
||||
@@ -137,12 +144,19 @@ app.registerExtension({
|
||||
const okWidget = this.widgets?.find(w => w.name === "output_keys");
|
||||
const otWidget = this.widgets?.find(w => w.name === "output_types");
|
||||
|
||||
const keys = okWidget?.value
|
||||
? okWidget.value.split(",").filter(k => k.trim())
|
||||
: [];
|
||||
const types = otWidget?.value
|
||||
? otWidget.value.split(",")
|
||||
: [];
|
||||
// Parse keys/types — try JSON array first, fall back to comma-split
|
||||
let keys = [];
|
||||
if (okWidget?.value) {
|
||||
try { keys = JSON.parse(okWidget.value); } catch (_) {
|
||||
keys = okWidget.value.split(",").map(k => k.trim()).filter(Boolean);
|
||||
}
|
||||
}
|
||||
let types = [];
|
||||
if (otWidget?.value) {
|
||||
try { types = JSON.parse(otWidget.value); } catch (_) {
|
||||
types = otWidget.value.split(",");
|
||||
}
|
||||
}
|
||||
|
||||
if (keys.length > 0) {
|
||||
// On load, LiteGraph already restored serialized outputs with links.
|
||||
@@ -159,8 +173,8 @@ app.registerExtension({
|
||||
} else if (this.outputs.length > 0) {
|
||||
// Widget values empty but serialized outputs exist — sync widgets
|
||||
// from the outputs LiteGraph already restored (fallback).
|
||||
if (okWidget) okWidget.value = this.outputs.map(o => o.name).join(",");
|
||||
if (otWidget) otWidget.value = this.outputs.map(o => o.type).join(",");
|
||||
if (okWidget) okWidget.value = JSON.stringify(this.outputs.map(o => o.name));
|
||||
if (otWidget) otWidget.value = JSON.stringify(this.outputs.map(o => o.type));
|
||||
}
|
||||
|
||||
this.setSize(this.computeSize());
|
||||
|
||||
Reference in New Issue
Block a user