Skip to content

Commit f4a2c74

Browse files
committed
feat: improve error dialog when gist actions is failed
1 parent 7e58cbe commit f4a2c74

File tree

2 files changed

+87
-27
lines changed

2 files changed

+87
-27
lines changed

rtl-spec/components/commands-publish-button.spec.tsx

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,21 @@ type GistCreateOpts = {
4040
public: boolean;
4141
};
4242

43+
class RequestError extends Error {
44+
public message: string;
45+
public status: number;
46+
47+
public constructor(message: string, status: number) {
48+
super(message);
49+
50+
this.message = message;
51+
this.status = status;
52+
}
53+
}
54+
4355
describe('Action button component', () => {
4456
const description = 'Electron Fiddle Gist';
45-
const errorMessage = '💀';
57+
const error = new RequestError("Don't be blue 💙", 401);
4658
let app: App;
4759
let mocktokit: OctokitMock;
4860
let state: AppState;
@@ -228,8 +240,9 @@ describe('Action button component', () => {
228240
});
229241

230242
it('handles an error in Gist publishing', async () => {
243+
state.showGenericDialog = vi.fn().mockReturnValue({ confirm: true });
231244
mocktokit.gists.create.mockImplementation(() => {
232-
throw new Error(errorMessage);
245+
throw new RequestError(error.message, error.status);
233246
});
234247

235248
state.editorMosaic.isEdited = true;
@@ -240,6 +253,11 @@ describe('Action button component', () => {
240253

241254
// On failure the editor should still be considered edited
242255
expect(state.editorMosaic.isEdited).toBe(true);
256+
expect(state.showGenericDialog).toHaveBeenCalledWith(
257+
expect.objectContaining({
258+
label: expect.stringContaining('Publishing Fiddle to GitHub failed.'),
259+
}),
260+
);
243261
});
244262

245263
it('can publish private gists', async () => {
@@ -292,16 +310,16 @@ describe('Action button component', () => {
292310
});
293311

294312
it('notifies the user if updating fails', async () => {
313+
state.showGenericDialog = vi.fn().mockReturnValue({ confirm: true });
295314
mocktokit.gists.update.mockImplementation(() => {
296-
throw new Error(errorMessage);
315+
throw new RequestError(error.message, error.status);
297316
});
298317

299318
await instance.performGistAction();
300319

301-
expect(window.ElectronFiddle.showWarningDialog).toHaveBeenCalledWith(
320+
expect(state.showGenericDialog).toHaveBeenCalledWith(
302321
expect.objectContaining({
303-
detail: expect.stringContaining(errorMessage),
304-
message: expect.stringContaining('Updating Fiddle Gist failed.'),
322+
label: expect.stringContaining('Updating Fiddle Gist failed.'),
305323
}),
306324
);
307325
});
@@ -325,16 +343,16 @@ describe('Action button component', () => {
325343
});
326344

327345
it('notifies the user if deleting fails', async () => {
346+
state.showGenericDialog = vi.fn().mockReturnValue({ confirm: true });
328347
mocktokit.gists.delete.mockImplementation(() => {
329-
throw new Error(errorMessage);
348+
throw new RequestError(error.message, error.status);
330349
});
331350

332351
await instance.performGistAction();
333352

334-
expect(window.ElectronFiddle.showWarningDialog).toHaveBeenCalledWith(
353+
expect(state.showGenericDialog).toHaveBeenCalledWith(
335354
expect.objectContaining({
336-
detail: expect.stringContaining(errorMessage),
337-
message: expect.stringContaining('Deleting Fiddle Gist failed.'),
355+
label: expect.stringContaining('Deleting Fiddle Gist failed.'),
338356
}),
339357
);
340358
});

src/renderer/components/commands-action-button.tsx

Lines changed: 59 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@ import { observer } from 'mobx-react';
1616
import {
1717
EditorId,
1818
EditorValues,
19+
GenericDialogType,
1920
GistActionState,
2021
GistActionType,
2122
PACKAGE_NAME,
2223
} from '../../interfaces';
24+
import { FIDDLE_GIST_DESCRIPTION_PLACEHOLDER } from '../constants';
2325
import { AppState } from '../state';
2426
import { ensureRequiredFiles } from '../utils/editor-utils';
2527
import { getOctokit } from '../utils/octokit';
@@ -98,7 +100,7 @@ export const GistActionButton = observer(
98100
}
99101

100102
private getFiddleDescriptionFromUser(): Promise<string | undefined> {
101-
const placeholder = 'Electron Fiddle Gist' as const;
103+
const placeholder = FIDDLE_GIST_DESCRIPTION_PLACEHOLDER;
102104
return this.props.appState.showInputDialog({
103105
defaultInput: placeholder,
104106
label: 'Please provide a brief description for your Fiddle Gist',
@@ -156,11 +158,23 @@ export const GistActionButton = observer(
156158
} catch (error: any) {
157159
console.warn(`Could not publish gist`, { error });
158160

159-
window.ElectronFiddle.showWarningDialog({
160-
message:
161-
'Publishing Fiddle to GitHub failed. Are you connected to the Internet?',
162-
detail: `GitHub encountered the following error: ${error.message}`,
163-
});
161+
if (error.status === 401 || error.status === 403) {
162+
const { confirm } = await this.props.appState.showGenericDialog({
163+
label: `Publishing Fiddle to GitHub failed. GitHub encountered the following error: ${error.message}`,
164+
ok: 'Update token',
165+
cancel: 'Close',
166+
type: GenericDialogType.warning,
167+
wantsInput: false,
168+
});
169+
170+
if (confirm) {
171+
this.showGitHubTokenSettings();
172+
}
173+
} else {
174+
await this.props.appState.showErrorDialog(
175+
`Publishing Fiddle to GitHub failed. Are you connected to the Internet? GitHub encountered the following error: ${error.message}`,
176+
);
177+
}
164178

165179
return false;
166180
}
@@ -230,12 +244,23 @@ export const GistActionButton = observer(
230244
} catch (error: any) {
231245
console.warn(`Could not update gist`, { error });
232246

233-
window.ElectronFiddle.showWarningDialog({
234-
message:
235-
'Updating Fiddle Gist failed. Are you connected to the Internet and is this your Gist?',
236-
detail: `GitHub encountered the following error: ${error.message}`,
237-
buttons: ['Ok'],
238-
});
247+
if (error.status === 401 || error.status === 403) {
248+
const { confirm } = await this.props.appState.showGenericDialog({
249+
label: `Updating Fiddle Gist failed. GitHub encountered the following error: ${error.message}`,
250+
ok: 'Update token',
251+
cancel: 'Close',
252+
type: GenericDialogType.warning,
253+
wantsInput: false,
254+
});
255+
256+
if (confirm) {
257+
this.showGitHubTokenSettings();
258+
}
259+
} else {
260+
await this.props.appState.showErrorDialog(
261+
`Updating Fiddle Gist failed. Are you connected to the Internet? GitHub encountered the following error: ${error.message}`,
262+
);
263+
}
239264
}
240265

241266
appState.activeGistAction = GistActionState.none;
@@ -262,11 +287,23 @@ export const GistActionButton = observer(
262287
} catch (error: any) {
263288
console.warn(`Could not delete gist`, { error });
264289

265-
window.ElectronFiddle.showWarningDialog({
266-
message:
267-
'Deleting Fiddle Gist failed. Are you connected to the Internet, is this your Gist, and have you loaded it?',
268-
detail: `GitHub encountered the following error: ${error.message}`,
269-
});
290+
if (error.status === 401 || error.status === 403) {
291+
const { confirm } = await this.props.appState.showGenericDialog({
292+
label: `Deleting Fiddle Gist failed. GitHub encountered the following error: ${error.message}`,
293+
ok: 'Update token',
294+
cancel: 'Close',
295+
type: GenericDialogType.warning,
296+
wantsInput: false,
297+
});
298+
299+
if (confirm) {
300+
this.showGitHubTokenSettings();
301+
}
302+
} else {
303+
await this.props.appState.showErrorDialog(
304+
`Deleting Fiddle Gist failed. Are you connected to the Internet? GitHub encountered the following error: ${error.message}`,
305+
);
306+
}
270307
}
271308

272309
appState.gistId = undefined;
@@ -455,5 +492,10 @@ export const GistActionButton = observer(
455492
.map(([id, content]) => [id, { filename: id, content }]),
456493
);
457494
};
495+
496+
private showGitHubTokenSettings() {
497+
this.props.appState.toggleSettings();
498+
this.props.appState.toggleAuthDialog();
499+
}
458500
},
459501
);

0 commit comments

Comments
 (0)