-
Notifications
You must be signed in to change notification settings - Fork 29
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
Handle errors of failed opening browser on Windows #840
Conversation
100f54b
to
0384abc
Compare
src/components/auth-provider.tsx
Outdated
try { | ||
await getIpcApi().authenticate(); | ||
} catch ( error ) { | ||
getIpcApi().showErrorMessageBox( { | ||
title: __( 'Failed to open browser' ), | ||
error, | ||
} ); | ||
} |
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.
I am thinking about creating HOF to avoid copy-paste, but in general it's an optional approach which I see.
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.
Calling showErrorMessageBox
directly from authenticate
and openSiteURL
seems like a good idea 👍 They're both part of ipc-handlers.ts
, so it should hopefully be relatively straightforward.
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.
I think this is a good approach 👍 Let's wrap it up and
const shouldMute = ( error: Error ) => { | ||
return ( | ||
error.message.startsWith( 'Failed to open:' ) && | ||
( error.message.endsWith( '(0x483)' ) || error.message.endsWith( '(0x800401F5)' ) ) |
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.
According to ChatGPT, the 0x483
error code indicates a different type of error. I'm not sure we should include it here…
The Windows error code 0x483 corresponds to the error message "ERROR_SWAPERROR." It indicates a system error related to the paging file or swap file. This error typically occurs when there is an issue accessing the paging file, which can be due to insufficient disk space, file corruption, or other disk-related issues.
To resolve this error, you might need to check your disk for errors, ensure there is adequate free space, and verify that your system's virtual memory settings are configured correctly.
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.
... file corruption...
- I think it's the reason.
Also, I left comment with example above // "Failed to open: 没有应用程序与此操作的指定文件有关联。 (0x483)"
.
I suppose it's teh same error, but maybe in Windows with Japan localization. Since according to breadcrumbs in Sentry - it's the same button.
So I would keep this condition here.
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.
I'm still not entirely convinced (0x483)
is a good fit for muting in code… If we're uncertain, I would rather have the info in Sentry and mute/resolve as needed there.
let message = ''; | ||
if ( url.startsWith( 'vscode://file/' ) ) { | ||
message = 'Studio is unable to open VS Code.'; | ||
} else if ( url.startsWith( 'phpstorm://open?file=' ) ) { | ||
message = 'Studio is unable to open PHPStorm.'; | ||
} else { | ||
message = 'Studio is unable to open your default browser.'; | ||
} | ||
|
||
message += 'Please ensure it is functioning correctly'; |
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.
let message = ''; | |
if ( url.startsWith( 'vscode://file/' ) ) { | |
message = 'Studio is unable to open VS Code.'; | |
} else if ( url.startsWith( 'phpstorm://open?file=' ) ) { | |
message = 'Studio is unable to open PHPStorm.'; | |
} else { | |
message = 'Studio is unable to open your default browser.'; | |
} | |
message += 'Please ensure it is functioning correctly'; | |
let message = ''; | |
if ( url.startsWith( 'vscode://file/' ) ) { | |
message = __( 'Studio is unable to open VS Code. Please ensure it is functioning correctly' ); | |
} else if ( url.startsWith( 'phpstorm://open?file=' ) ) { | |
message = __( 'Studio is unable to open PHPStorm. Please ensure it is functioning correctly' ); | |
} else { | |
message = __( 'Studio is unable to open your default browser. Please ensure it is functioning correctly' ); | |
} |
Let's make the strings translatable.
src/lib/oauth.ts
Outdated
const authUrl = `${ WP_AUTHORIZE_ENDPOINT }?response_type=token&client_id=${ CLIENT_ID }&redirect_uri=${ encodeURIComponent( | ||
REDIRECT_URI | ||
) }&scope=${ encodeURIComponent( SCOPES ) }`; | ||
shell.openExternal( authUrl ); | ||
|
||
await shellOpenExternalWrapper( authUrl ); |
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.
Is this a leftover? shellOpenExternalWrapper
isn't async
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.
No, it's async and we handle try/catch in the upper level
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.
UPDATE: With my latest changes we don't need it
src/components/auth-provider.tsx
Outdated
try { | ||
await getIpcApi().authenticate(); | ||
} catch ( error ) { | ||
getIpcApi().showErrorMessageBox( { | ||
title: __( 'Failed to open browser' ), | ||
error, | ||
} ); | ||
} |
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.
Calling showErrorMessageBox
directly from authenticate
and openSiteURL
seems like a good idea 👍 They're both part of ipc-handlers.ts
, so it should hopefully be relatively straightforward.
src/ipc-handlers.ts
Outdated
} | ||
|
||
export async function openURL( event: IpcMainInvokeEvent, url: string ) { | ||
return shell.openExternal( url ); | ||
return shellOpenExternalWrapper( url ); |
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.
I will remove this return
and related conde on frontend on Monday, for consistency. We don't need it to be async function.
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.
The same for authenticate
function
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.
LGTM 👍 I took the liberty of pushing a few small tweaks to avoid the additional back and forth, given that this has already been a gnarly issue.
The only remaining question I see is what to do about the (0x483)
error. I'm not sure we want to mute it, since it seems only tangentially related. We can archive or resolve the issue in Sentry, but it might still be interesting to capture that data.
src/ipc-handlers.ts
Outdated
@@ -639,8 +640,8 @@ export function logRendererMessage( | |||
writeLogToFile( level, processId, ...args ); | |||
} | |||
|
|||
export async function authenticate( _event: IpcMainInvokeEvent ): Promise< void > { | |||
return oauthClient.authenticate(); | |||
export function authenticate( _event: IpcMainInvokeEvent ): void { |
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 function authenticate( _event: IpcMainInvokeEvent ): void { | |
export function authenticate( _event: IpcMainInvokeEvent ) { |
Maybe someone disagrees with me, but I don't think it's necessary to explicitly add a void
return type here.
// "Failed to open: Application not found (0x800401F5)" | ||
const shouldMute = ( error: Error ) => { | ||
return ( | ||
error.message.startsWith( 'Failed to open:' ) && |
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.
error.message.startsWith( 'Failed to open:' ) && |
As the error message can be in different languages, I think it's better to look just at the error code and disregard the natural language part of the message.
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.
I was thinking about it and wanted to be more specific and mute as less as possible, so that we could be aware about other errors, is they appear in other languages.
This conditions which I added are specific for cases that we already have in Sentry. So I wanted to monitor Sentry in the future and update condition step by step.
Did you get what I mean and my thoughts? 😅
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.
I understand, but I feel this strikes an odd balance between muting in code and submitting in Sentry. If we should mute anything in code, I would argue we should only look for the (0x800401F5)
error code.
I would honestly be open to not muting anything in the code, too, if we think that's a clearer approach.
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.
I see you point. Updated the condition to have only (0x800401F5)
.
I would honestly be open to not muting anything in the code, too, if we think that's a clearer approach.
Hm, didn't get it. From my perspective - we know about this specific issue with browser and if we not mute it, then it will just flood our logs in Sentry. It's the main point why I want to mute it. To avoid distraction of us with these errors.
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.
From my perspective - we know about this specific issue with browser and if we not mute it, then it will just flood our logs in Sentry
I agree we want to mute it, but Sentry also has built-in tools to do that. I'm OK with doing it in code for this specific error, but principally, I think it's best to mute in Sentry rather than in code.
const shouldMute = ( error: Error ) => { | ||
return ( | ||
error.message.startsWith( 'Failed to open:' ) && | ||
( error.message.endsWith( '(0x483)' ) || error.message.endsWith( '(0x800401F5)' ) ) |
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.
I'm still not entirely convinced (0x483)
is a good fit for muting in code… If we're uncertain, I would rather have the info in Sentry and mute/resolve as needed there.
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.
One more thing: let's move this file to src/lib
and use kebab case for the file name (shell-open-external-wrapper.ts
)
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.
Done
a02c647
to
489dd90
Compare
Related issues
Proposed Changes
We had case when users could not open browser and they didn't see any errors.
With this PR if opening browser of IDE is failed - we render popup with error.
Testing Instructions
6.1
authenticate
: "Sync" -> "Log in to WordPress.com" button6.2
openSiteURL
: "Import/Export" -> then import your backup -> at the end of importing you will see "Open site" button, click on it6.3
openSiteURL
: "WP admin" link in the header6.4
openSiteURL
:"Open site" link in the header6.5
openSiteURL
:"Open site" link in the header6.6
openSiteURL
:"Overview" -> Click on the preview (under "Theme" sub title)6.7
openSiteURL
:"Overview" -> "Site Editor" && "Styles" && "Patterns" && "Navigation" && "Templates" && "Pages"6.8
openURL
: in top right corner of the Studio's window click on(?)
6.9
openURL
: "Import / Export" -> Click on "Learn more" in the tab description6.10 "Menu bar" -> "Studio" -> "About Studio" -> Click on any link
6.11 "Menu bar" -> "Help" -> "Studio Help"