-
Notifications
You must be signed in to change notification settings - Fork 3.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: catch errors from web container and show in actionable alert so user can send them to AI for fixing #856
feat: catch errors from web container and show in actionable alert so user can send them to AI for fixing #856
Conversation
I made a small drawing.
I would start the with the most challenging: Capture all errors from all Containers and Browser Console and save it to Event Logs. Right now Event Logs is missing 70% of errors. I checked that. |
I was not able to capture these errors and feed it back to the LLM. As there are not only Terminal Errors but also errors only appearing when rendered in the browser. We might also include these into the fix errors component. Let me know what you think |
I have have different approaches: We need to identify which container each error originates from. Unique Iframe IDs: Instead of relying solely on the source in the postMessage, which can be ambiguous, let's use unique IDs for each Webcontainer's iframe. This way, you can be sure of the origin of the log. This could be a simple sequential number or a more sophisticated identifier. Stringify Error Objects: Instead of just getting the error message, try to serialize the entire Error object, including the stack trace when available (for exceptions). This often provides much more context. Browser Extension Assistance: Content Script: If you absolutely need a very high level of certainty, a browser extension's content script might be able to intercept console messages and send them to the background script which, in turn, can send it to a web page. This goes beyond the usual restrictions of a web page's script. But this means user need to install an extension Inline script in : Ensure that the script that overrides console.error, window.onerror, and sets up the postMessage listener within the iframe is in an inline script in the iframe's . This is the best way to ensure that it runs as early as possible to intercept errors that may occur during page load. Use Web Worker (for some web container implementations): If your web container implementation uses a web worker instead of iframe, the errors in worker are not caught by window.onerror. You have to use worker.onerror to catch errors in the web worker. Introduce a Centralized Logging Function (Within the Iframe): Unified Function: In the iframe, instead of calling window.parent.postMessage directly, call a centralized logging function inside your iframe that calls postMessage, but also include the iframe id, so if postMessage is somehow blocked or lost, you can add a backup method in the log function Fallback: Even with browser methods, sending a copy of the logs to a server-side endpoint offers a backup if there's a rare scenario where client-side capturing fails. |
I get strong vibes of ChatGPT writing this :D
|
is this line showing all the console logs from preview?? webcontainer.on('preview-message', (message) => {
console.log('WebContainer preview message:', message);
}); |
One is for sure. We do not need to dive into the Webcontainer even it is closed source. At some point we should get rid of closed source as we cannot control the inside. We see these errors in browsers console and can grab them. What we can see we should be able to programmatically get. My ideas here are:
Core Function: The extension acts as a real-time console log streamer. It intercepts console.log, console.warn, console.error, and other relevant output, as it appears in the browser's DevTools console. Leveraging the DevTools Protocol from a Browser Extension:
Intercept Communication: Instead of trying to capture the logs after they are generated, we might be able to capture them before they even reach the browser's console by intercepting the communication What do you guys think? |
I tried and did not get all errors with that. |
not all errors are from preview, some errors are from bolt itself which we can ignore as those are not related to the project that is being built. we just need the errors that are originated from the preview window only |
@thecodacus absolutely right. Anyone more capable of capturing them. Will try tomorrow and update you guys Maybe we can join forces as this preview issue seems to be a big road blocker |
What errors did you try? What you proposed before with extensions is not feasible. Can you share gist of exported chat that shows what kinds of errors it does not catch? |
That will not really work because errors do not come from webcontainer. What is happening is this:
That iframe is on other domain we do not control, so we can't really go in and capture things ourselves So we get back to what I shared before.
|
Ouh wait, just found something ineresting We can ask webcontainer to inject script that will be loaded in all preview urls that are open. |
then we can also monkeypatch the console.log to have additional function calls, and replace the original one with our modified one and this is what it says about intercepting the errors // Store the original error handling function
const originalOnError = window.onerror;
const originalUnhandledRejection = window.onunhandledrejection;
// Global error handler
window.onerror = function(message, source, lineno, colno, error) {
const errorInfo = {
message,
source,
lineno,
colno,
timestamp: new Date().toISOString(),
type: 'uncaught-error'
};
try {
// Process the error
processError(error, errorInfo);
} catch (processingError) {
console.error('Error in error processing:', processingError);
}
// Call the original handler if it exists
if (originalOnError) {
return originalOnError.apply(this, arguments);
}
// Rethrow the error by default
return false;
};
// Handle Promise rejections
window.onunhandledrejection = function(event) {
const errorInfo = {
message: event.reason?.message || 'Unhandled Promise Rejection',
timestamp: new Date().toISOString(),
type: 'unhandled-rejection'
};
try {
// Process the error
processError(event.reason, errorInfo);
} catch (processingError) {
console.error('Error in promise rejection processing:', processingError);
}
// Call the original handler if it exists
if (originalUnhandledRejection) {
return originalUnhandledRejection.apply(this, arguments);
}
// Prevent the default handling
event.preventDefault();
}; |
Guys that is really high level. Thanks for the input. I must say that this closed source webcontainer thing is really something no developer likes but tolerates. At some point we can replace that but not now. |
This is already returned, I already showed in this PR that webcontainer returns unhandled rejections and errors. |
I guess we will start with this. let see how it looks in the UI and the full flow, then we will be able to see if its missing any thing |
I posted this earlier. There are react errors in the app inside webcontainer. Also other errors. The best would be to combine the existing fix error logic in the Terminal pull request with this one so we do not need to implement a new fixing logic. Inside we can ask LLm to fix both as these are running in different containers. We could do 2 in one. Is there a way we could talk also not just write? That would be awesome |
I am going to list the categories of errors and we can start anticipating which can appear. I see bolt fails List of possible errors: Error List:
|
Error handling ist the most critical thing here. I tested bolt.new extensively. It fails too many times because error handling is not working very well. Step 1: Error Capturing |
Hm, need to reproduce that react error and see if code I did here reacts to it. So, want something captured? Share gist of a chat where failure happens but is not detected. |
Connected with merged @thecodacus terminal errors code |
app/types/actions.ts
Outdated
@@ -1,4 +1,4 @@ | |||
export type ActionType = 'file' | 'shell'; | |||
export type ActionType = 'file' | 'shell' | 'preview'; | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
export type ActionType = 'file' | 'shell' | 'preview';
is this change required? i don't see it being used anywhere and relevant
I am gonna test this now. will update once tested with different errors |
I still have the React Error which is not captured by the Error handling system Here is a screenshot Here is the Chat export |
Terminal errors work very good, great job guys. One thing for the terminal errors feedback. If you cancel the current command in terminal, the Terminal error is showing and you can let it fix, but have to start the npm run dev on your own. There should be an addition to run npm run dev in the end. |
That was the part I meant earlier. If we can get the errors we see in the console we can just send it to the LLM and let it fix. What happens is there is an import React missing somewhere and it cannot run the Preview. |
yes manually interrupting terminal command recognize it as error cuz it throws an error exit code. will try to find the exact error code for that and exclude it from throwing errors later @wonderwhy-er the app is throwing error in my case reason is, this file is also imported in server code and I have seen app throwing error anytime where in server code an import is done where we have a nanostore created. even if we don't use it in the code in runtime just by importing it throws error |
@thecodacus I just pushed two fixes you suggested. |
@faddy19 I just tested on your chat and it worked in this PR |
Let me retest it. I might missed something. Thanks a lot for pointing this out |
awesome great, one more change I think would be great, but maybe optional.. here is what claude suggested function cleanStackTrace(stackTrace: string): string {
// Function to clean a single URL
const cleanUrl = (url: string): string => {
const regex = /^https?:\/\/[^\/]+\.webcontainer-api\.io(\/.*)?$/;
if (!regex.test(url)) {
return url;
}
const pathRegex = /^https?:\/\/[^\/]+\.webcontainer-api\.io\/(.*?)$/;
const match = url.match(pathRegex);
return match?.[1] || '';
};
// Split the stack trace into lines and process each line
return stackTrace.split('\n').map(line => {
// Match any URL in the line that contains webcontainer-api.io
return line.replace(
/(https?:\/\/[^\/]+\.webcontainer-api\.io\/[^\s\)]+)/g,
match => cleanUrl(match)
);
}).join('\n');
} Test it with your stack trace const stackTrace = `Error
at printWarning (https://6toq0kapqpmjiyrdqgbkv347gyeld0-2tu1--5173--c8c182a3.local-corp.webcontainer-api.io/node_modules/.vite/deps/react-dom.js?v=9d11fbfb:519:38)
at error (https://6toq0kapqpmjiyrdqgbkv347gyeld0-2tu1--5173--c8c182a3.local-corp.webcontainer-api.io/node_modules/.vite/deps/react-dom.js?v=9d11fbfb:503:15)
at Object.render (https://6toq0kapqpmjiyrdqgbkv347gyeld0-2tu1--5173--c8c182a3.local-corp.webcontainer-api.io/node_modules/.vite/deps/react-dom.js?v=9d11fbfb:21444:13)
at https://6toq0kapqpmjiyrdqgbkv347gyeld0-2tu1--5173--c8c182a3.local-corp.webcontainer-api.io/src/main.jsx:4:10`;
console.log(cleanStackTrace(stackTrace)); This will output:
|
Good suggestions, pushed in url cleanup, tested on couple of examples quick, need to go now. |
yeah.. I will do some testing. and will merge if all look good |
Next step would be that we automatically fix these errors in the background that we do not bother with Ask Bolt or Fix this. We want to have a preview. Or we implement a toggle in Settings and say autoapprove error fixing and Terminal commands. That would give control What do you think? |
I think you can already push to main @thecodacus |
One more idea: Would it make sense to put a panic button in there so if the preview or app get stuck, the user clicks it and we send a prompt to the llm to check for errors in terminal and the application and to fix it? It is impossible to capture all errors and some standard user might not be able to copy paste the error |
for now I thing this PR is capturing the Preview error just fine. its good to merge |
…alert so user can send them to AI for fixing (stackblitz-labs#856) * Catch errors from web container * Show fix error popup on errors in preview * Remove unneeded action type * PR comments * Cleanup urls in stacktrace --------- Co-authored-by: Anirban Kar <[email protected]>
Summary
This PR introduces enhancements to error handling for web container previews
Key Changes
Error Handling for Previews:
User Interface Improvements:
Updated ChatAlert component to display context-specific error messages for terminal and preview errors.
Added changes to readme