mirror of
https://github.com/pybricks/pybricks-code.git
synced 2026-09-15 02:54:07 +00:00
add special notification for unexpected errors
Since these errors are not expected, we want to make it really easy to report them.
This commit is contained in:
@@ -1,13 +1,13 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Copyright (c) 2020 The Pybricks Authors
|
||||
// Copyright (c) 2021 The Pybricks Authors
|
||||
|
||||
// provides translation for notification text
|
||||
|
||||
import { Replacements, useI18n } from '@shopify/react-i18n';
|
||||
import React from 'react';
|
||||
import { MessageId } from './notification-i18n';
|
||||
import en from './notification-i18n.en.json';
|
||||
|
||||
// provides translation for notification text
|
||||
|
||||
type OwnProps = {
|
||||
messageId: MessageId;
|
||||
replacements?: Replacements;
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Copyright (c) 2021 The Pybricks Authors
|
||||
|
||||
// Provides special notification contents for unexpected errors.
|
||||
|
||||
import { AnchorButton, Button, ButtonGroup, Intent } from '@blueprintjs/core';
|
||||
import { useI18n } from '@shopify/react-i18n';
|
||||
import React from 'react';
|
||||
import { MessageId } from './notification-i18n';
|
||||
import en from './notification-i18n.en.json';
|
||||
|
||||
type OwnProps = {
|
||||
messageId: MessageId;
|
||||
err: Error;
|
||||
};
|
||||
|
||||
export default function UnexpectedErrorNotification(props: OwnProps): JSX.Element {
|
||||
const [i18n] = useI18n({
|
||||
id: 'notification',
|
||||
translations: { en },
|
||||
fallback: en,
|
||||
});
|
||||
const { messageId, err } = props;
|
||||
return (
|
||||
<>
|
||||
<p>{i18n.translate(messageId, { errorMessage: err.message })}</p>
|
||||
<div>
|
||||
<ButtonGroup minimal={true} fill={true}>
|
||||
<Button
|
||||
intent={Intent.DANGER}
|
||||
icon="duplicate"
|
||||
onClick={() =>
|
||||
navigator.clipboard.writeText(
|
||||
`\`\`\`\n${err.stack || err.message}\n\`\`\``,
|
||||
)
|
||||
}
|
||||
>
|
||||
{i18n.translate(MessageId.CopyErrorMessage)}
|
||||
</Button>
|
||||
<AnchorButton
|
||||
intent={Intent.DANGER}
|
||||
icon="virus"
|
||||
href={`https://github.com/pybricks/support/issues?q=${encodeURIComponent(
|
||||
'is:issue',
|
||||
)}+${encodeURIComponent(err.message)}`}
|
||||
target="_blank"
|
||||
>
|
||||
{i18n.translate(MessageId.ReportBug)}
|
||||
</AnchorButton>
|
||||
</ButtonGroup>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
{
|
||||
"copyErrorMessage": "Copy Error Message",
|
||||
"reportBug": "Report Bug",
|
||||
"ble": {
|
||||
"gattPermission": "The web browser did not give permission to use Bluetooth Low Energy",
|
||||
"gattServiceNotFound": "Connected to hub but failed to get {serviceName} service. Try removing the \"{hubName}\" device in your OS Bluetooth settings, then try again.",
|
||||
"noWebBluetooth": "This web browser does not support Web Bluetooth or it is not enabled.",
|
||||
"connectFailed": "Unexpected error while trying to connect. Check console log and report the error."
|
||||
"unexpectedError": "Unexpected error while trying to connect: {errorMessage}"
|
||||
},
|
||||
"editor": {
|
||||
"programChanged": {
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
// Notification translation keys.
|
||||
|
||||
export enum MessageId {
|
||||
BleConnectFailed = 'ble.connectFailed',
|
||||
CopyErrorMessage = 'copyErrorMessage',
|
||||
ReportBug = 'reportBug',
|
||||
BleUnexpectedError = 'ble.unexpectedError',
|
||||
BleGattPermission = 'ble.gattPermission',
|
||||
BleGattServiceNotFound = 'ble.gattServiceNotFound',
|
||||
BleNoWebBluetooth = 'ble.noWebBluetooth',
|
||||
|
||||
@@ -27,7 +27,9 @@ test.each([
|
||||
reason: BleDeviceFailToConnectReasonType.Unknown,
|
||||
err: { name: 'test', message: 'unknown' },
|
||||
}),
|
||||
bootloaderDidFailToConnect(BootloaderConnectionFailureReason.Unknown),
|
||||
bootloaderDidFailToConnect(BootloaderConnectionFailureReason.Unknown, <Error>{
|
||||
message: 'test',
|
||||
}),
|
||||
bootloaderDidFailToConnect(BootloaderConnectionFailureReason.NoWebBluetooth),
|
||||
bootloaderDidFailToConnect(BootloaderConnectionFailureReason.GattServiceNotFound),
|
||||
storageChanged('test'),
|
||||
|
||||
@@ -30,6 +30,7 @@ import { MpyActionType, MpyDidFailToCompileAction } from '../actions/mpy';
|
||||
import { NotificationActionType, NotificationAddAction } from '../actions/notification';
|
||||
import { ServiceWorkerActionType } from '../actions/service-worker';
|
||||
import Notification from '../components/Notification';
|
||||
import UnexpectedErrorNotification from '../components/UnexpectedErrorNotification';
|
||||
import { MessageId } from '../components/notification-i18n';
|
||||
import { appName } from '../settings/ui';
|
||||
|
||||
@@ -140,6 +141,17 @@ function* showSingleton(
|
||||
);
|
||||
}
|
||||
|
||||
/** Shows a special notification for unexpected errors. */
|
||||
function* showUnexpectedError(messageId: MessageId, err: Error): Generator {
|
||||
const { toaster } = (yield getContext('notification')) as NotificationContext;
|
||||
toaster.show({
|
||||
intent: mapIntent(Level.Error),
|
||||
icon: mapIcon(Level.Error),
|
||||
message: React.createElement(UnexpectedErrorNotification, { messageId, err }),
|
||||
timeout: 0,
|
||||
});
|
||||
}
|
||||
|
||||
function* showBleDeviceDidFailToConnectError(
|
||||
action: BleDeviceDidFailToConnectAction,
|
||||
): Generator {
|
||||
@@ -165,7 +177,7 @@ function* showBleDeviceDidFailToConnectError(
|
||||
);
|
||||
break;
|
||||
case BleDeviceFailToConnectReasonType.Unknown:
|
||||
yield* showSingleton(Level.Error, MessageId.BleConnectFailed);
|
||||
yield* showUnexpectedError(MessageId.BleUnexpectedError, action.err);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -191,7 +203,7 @@ function* showBootloaderDidFailToConnectError(
|
||||
);
|
||||
break;
|
||||
case BootloaderConnectionFailureReason.Unknown:
|
||||
yield* showSingleton(Level.Error, MessageId.BleConnectFailed);
|
||||
yield* showUnexpectedError(MessageId.BleUnexpectedError, action.err);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user