Skip to content

Commit 0b686e9

Browse files
Copilotna-trium-144
andcommitted
Address code review feedback - fix interrupt buffer and error handling
Co-authored-by: na-trium-144 <100704180+na-trium-144@users.noreply.github.com>
1 parent 00f3e85 commit 0b686e9

File tree

2 files changed

+38
-62
lines changed

2 files changed

+38
-62
lines changed

app/terminal/ruby/runtime.tsx

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ export function RubyProvider({ children }: { children: ReactNode }) {
6363
Map<number, [(payload: any) => void, (error: string) => void]>
6464
>(new Map());
6565
const nextMessageId = useRef<number>(0);
66-
const interruptBuffer = useRef<Uint8Array | null>(null);
6766

6867
function postMessage<T>({ type, payload }: MessageToWorker) {
6968
const id = nextMessageId.current++;
@@ -109,9 +108,9 @@ export function RubyProvider({ children }: { children: ReactNode }) {
109108
}, []);
110109

111110
const interrupt = useCallback(() => {
112-
if (interruptBuffer.current) {
113-
interruptBuffer.current[0] = 2;
114-
}
111+
// TODO: Implement interrupt functionality for Ruby
112+
// Ruby WASM doesn't currently support interrupts like Pyodide does
113+
console.warn("Ruby interrupt is not yet implemented");
115114
}, []);
116115

117116
const runCommand = useCallback(
@@ -123,10 +122,6 @@ export function RubyProvider({ children }: { children: ReactNode }) {
123122
return [{ type: "error", message: "Ruby VM is not ready yet." }];
124123
}
125124

126-
if (interruptBuffer.current) {
127-
interruptBuffer.current[0] = 0;
128-
}
129-
130125
const { output, updatedFiles } = await postMessage<RunPayloadFromWorker>({
131126
type: "runRuby",
132127
payload: { code },
@@ -166,9 +161,6 @@ export function RubyProvider({ children }: { children: ReactNode }) {
166161
if (!workerRef.current || !ready) {
167162
return [{ type: "error", message: "Ruby VM is not ready yet." }];
168163
}
169-
if (interruptBuffer.current) {
170-
interruptBuffer.current[0] = 0;
171-
}
172164
return mutex.current.runExclusive(async () => {
173165
const { output, updatedFiles } =
174166
await postMessage<RunPayloadFromWorker>({

public/ruby.worker.js

Lines changed: 35 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -109,15 +109,37 @@ function flushOutput() {
109109
}
110110
stderrBuffer = lines[lines.length - 1];
111111
}
112-
// Final flush if there's remaining text
113-
if (stdoutBuffer) {
112+
// Final flush if there's remaining non-empty text
113+
if (stdoutBuffer && stdoutBuffer.trim()) {
114114
rubyOutput.push({ type: 'stdout', message: stdoutBuffer });
115-
stdoutBuffer = "";
116115
}
117-
if (stderrBuffer) {
116+
stdoutBuffer = "";
117+
118+
if (stderrBuffer && stderrBuffer.trim()) {
118119
rubyOutput.push({ type: 'stderr', message: stderrBuffer });
119-
stderrBuffer = "";
120120
}
121+
stderrBuffer = "";
122+
}
123+
124+
function formatRubyError(error) {
125+
if (!(error instanceof Error)) {
126+
return `予期せぬエラー: ${String(error).trim()}`;
127+
}
128+
129+
let errorMessage = error.message;
130+
131+
// Clean up Ruby error messages by filtering out internal eval lines
132+
if (errorMessage.includes('Traceback') || errorMessage.includes('Error')) {
133+
const lines = errorMessage.split('\n');
134+
// Keep lines that either don't contain (eval), or contain Error, or have line numbers
135+
errorMessage = lines.filter(line =>
136+
!line.includes('(eval)') ||
137+
line.includes('Error') ||
138+
line.match(/:\d+:/)
139+
).join('\n').trim();
140+
}
141+
142+
return errorMessage;
121143
}
122144

123145
async function runRuby(id, payload) {
@@ -151,30 +173,10 @@ async function runRuby(id, payload) {
151173
console.log(e);
152174
flushOutput();
153175

154-
if (e instanceof Error) {
155-
let errorMessage = e.message;
156-
157-
// Clean up Ruby error messages
158-
if (errorMessage.includes('Traceback') || errorMessage.includes('Error')) {
159-
const lines = errorMessage.split('\n');
160-
// Filter out internal lines
161-
errorMessage = lines.filter(line =>
162-
!line.includes('(eval)') ||
163-
line.includes('Error') ||
164-
line.match(/:\d+:/)
165-
).join('\n').trim();
166-
}
167-
168-
rubyOutput.push({
169-
type: 'error',
170-
message: errorMessage
171-
});
172-
} else {
173-
rubyOutput.push({
174-
type: 'error',
175-
message: `予期せぬエラー: ${String(e).trim()}`
176-
});
177-
}
176+
rubyOutput.push({
177+
type: 'error',
178+
message: formatRubyError(e)
179+
});
178180
}
179181

180182
const updatedFiles = readAllFiles();
@@ -222,28 +224,10 @@ async function runFile(id, payload) {
222224
console.log(e);
223225
flushOutput();
224226

225-
if (e instanceof Error) {
226-
let errorMessage = e.message;
227-
228-
if (errorMessage.includes('Traceback') || errorMessage.includes('Error')) {
229-
const lines = errorMessage.split('\n');
230-
errorMessage = lines.filter(line =>
231-
!line.includes('(eval)') ||
232-
line.includes('Error') ||
233-
line.match(/:\d+:/)
234-
).join('\n').trim();
235-
}
236-
237-
rubyOutput.push({
238-
type: 'error',
239-
message: errorMessage
240-
});
241-
} else {
242-
rubyOutput.push({
243-
type: 'error',
244-
message: `予期せぬエラー: ${String(e).trim()}`
245-
});
246-
}
227+
rubyOutput.push({
228+
type: 'error',
229+
message: formatRubyError(e)
230+
});
247231
}
248232

249233
const updatedFiles = readAllFiles();

0 commit comments

Comments
 (0)