Add robust fallback mechanism with timeout-based initialization
- Wrapped initial fit logic in comprehensive try-catch with multiple fallback strategies - Added timeout-based fallback (2 seconds) to ensure terminal always gets initialized - Enhanced error handling to prevent blank terminal on initialization failure - Added cleanup of fallback timeout when WebSocket connects successfully - Maintains all existing functionality and improves reliability Bump version to 0.3.30 Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "textual-webterm"
|
name = "textual-webterm"
|
||||||
version = "0.3.29"
|
version = "0.3.30"
|
||||||
description = "Serve terminal sessions over the web"
|
description = "Serve terminal sessions over the web"
|
||||||
authors = ["Will McGugan <will@textualize.io>"]
|
authors = ["Will McGugan <will@textualize.io>"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|||||||
@@ -14665,13 +14665,20 @@ class WebTerminal {
|
|||||||
this.send(["resize", { width: fallback.cols, height: fallback.rows }]);
|
this.send(["resize", { width: fallback.cols, height: fallback.rows }]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (dims && this.isValidSize(dims.cols, dims.rows) && this.isTerminalReady()) {
|
try {
|
||||||
this.terminal.resize(dims.cols, dims.rows);
|
if (dims && this.isValidSize(dims.cols, dims.rows) && this.isTerminalReady()) {
|
||||||
this.resizeState.lastValidSize = dims;
|
this.terminal.resize(dims.cols, dims.rows);
|
||||||
this.send(["resize", { width: dims.cols, height: dims.rows }]);
|
this.resizeState.lastValidSize = dims;
|
||||||
} else {
|
this.send(["resize", { width: dims.cols, height: dims.rows }]);
|
||||||
const reason = !dims ? "proposeDimensions failed" : !this.isValidSize(dims.cols, dims.rows) ? `invalid dimensions: ${dims.cols}x${dims.rows}` : "terminal not ready";
|
} else {
|
||||||
console.warn(`Initial fit ${reason}, using fallback`);
|
const reason = !dims ? "proposeDimensions failed" : !this.isValidSize(dims.cols, dims.rows) ? `invalid dimensions: ${dims.cols}x${dims.rows}` : "terminal not ready";
|
||||||
|
console.warn(`Initial fit ${reason}, using fallback`);
|
||||||
|
this.terminal.resize(fallback.cols, fallback.rows);
|
||||||
|
this.resizeState.lastValidSize = fallback;
|
||||||
|
this.send(["resize", { width: fallback.cols, height: fallback.rows }]);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.warn(`Initial fit failed with exception: ${e.message}, using fallback`);
|
||||||
this.terminal.resize(fallback.cols, fallback.rows);
|
this.terminal.resize(fallback.cols, fallback.rows);
|
||||||
this.resizeState.lastValidSize = fallback;
|
this.resizeState.lastValidSize = fallback;
|
||||||
this.send(["resize", { width: fallback.cols, height: fallback.rows }]);
|
this.send(["resize", { width: fallback.cols, height: fallback.rows }]);
|
||||||
@@ -14684,6 +14691,22 @@ class WebTerminal {
|
|||||||
} else {
|
} else {
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
const fallbackTimeout = setTimeout(() => {
|
||||||
|
if (!this.resizeState.lastValidSize) {
|
||||||
|
console.warn("Initial fit timed out, applying fallback dimensions");
|
||||||
|
const fallback = { cols: 80, rows: 24 };
|
||||||
|
try {
|
||||||
|
this.terminal.resize(fallback.cols, fallback.rows);
|
||||||
|
this.resizeState.lastValidSize = fallback;
|
||||||
|
this.send(["resize", { width: fallback.cols, height: fallback.rows }]);
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Fallback resize failed:", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 2000);
|
||||||
|
this.socket?.addEventListener("open", () => {
|
||||||
|
clearTimeout(fallbackTimeout);
|
||||||
|
});
|
||||||
this.terminal.focus();
|
this.terminal.focus();
|
||||||
});
|
});
|
||||||
this.socket.addEventListener("close", () => {
|
this.socket.addEventListener("close", () => {
|
||||||
|
|||||||
@@ -373,15 +373,24 @@ class WebTerminal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Validate dimensions and terminal readiness before applying
|
// Validate dimensions and terminal readiness before applying
|
||||||
if (dims && this.isValidSize(dims.cols, dims.rows) && this.isTerminalReady()) {
|
// Use a defensive approach with multiple fallback strategies
|
||||||
this.terminal.resize(dims.cols, dims.rows);
|
try {
|
||||||
this.resizeState.lastValidSize = dims;
|
if (dims && this.isValidSize(dims.cols, dims.rows) && this.isTerminalReady()) {
|
||||||
this.send(["resize", { width: dims.cols, height: dims.rows }]);
|
this.terminal.resize(dims.cols, dims.rows);
|
||||||
} else {
|
this.resizeState.lastValidSize = dims;
|
||||||
const reason = !dims ? "proposeDimensions failed" :
|
this.send(["resize", { width: dims.cols, height: dims.rows }]);
|
||||||
!this.isValidSize(dims.cols, dims.rows) ? `invalid dimensions: ${dims.cols}x${dims.rows}` :
|
} else {
|
||||||
"terminal not ready";
|
const reason = !dims ? "proposeDimensions failed" :
|
||||||
console.warn(`Initial fit ${reason}, using fallback`);
|
!this.isValidSize(dims.cols, dims.rows) ? `invalid dimensions: ${dims.cols}x${dims.rows}` :
|
||||||
|
"terminal not ready";
|
||||||
|
console.warn(`Initial fit ${reason}, using fallback`);
|
||||||
|
this.terminal.resize(fallback.cols, fallback.rows);
|
||||||
|
this.resizeState.lastValidSize = fallback;
|
||||||
|
this.send(["resize", { width: fallback.cols, height: fallback.rows }]);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.warn(`Initial fit failed with exception: ${e.message}, using fallback`);
|
||||||
|
// If anything goes wrong, use the fallback dimensions
|
||||||
this.terminal.resize(fallback.cols, fallback.rows);
|
this.terminal.resize(fallback.cols, fallback.rows);
|
||||||
this.resizeState.lastValidSize = fallback;
|
this.resizeState.lastValidSize = fallback;
|
||||||
this.send(["resize", { width: fallback.cols, height: fallback.rows }]);
|
this.send(["resize", { width: fallback.cols, height: fallback.rows }]);
|
||||||
@@ -396,6 +405,26 @@ class WebTerminal {
|
|||||||
} else {
|
} else {
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add a timeout-based fallback in case the initial fit never succeeds
|
||||||
|
const fallbackTimeout = setTimeout(() => {
|
||||||
|
if (!this.resizeState.lastValidSize) {
|
||||||
|
console.warn("Initial fit timed out, applying fallback dimensions");
|
||||||
|
const fallback = { cols: 80, rows: 24 };
|
||||||
|
try {
|
||||||
|
this.terminal.resize(fallback.cols, fallback.rows);
|
||||||
|
this.resizeState.lastValidSize = fallback;
|
||||||
|
this.send(["resize", { width: fallback.cols, height: fallback.rows }]);
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Fallback resize failed:", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 2000);
|
||||||
|
|
||||||
|
// Clean up timeout when WebSocket connects
|
||||||
|
this.socket?.addEventListener('open', () => {
|
||||||
|
clearTimeout(fallbackTimeout);
|
||||||
|
});
|
||||||
|
|
||||||
// Focus terminal
|
// Focus terminal
|
||||||
this.terminal.focus();
|
this.terminal.focus();
|
||||||
|
|||||||
Reference in New Issue
Block a user