Skip to content

Commit c1a7e8c

Browse files
authored
Warn when using qgrid > 1.1.1 (microsoft#11280)
For #11245 * Warn when using qgrid version > 1.1.1 * For now hardcoded to check only qgrid version 1.1.1. * Should be easy enough to add others, didn't want to make it too generic.
1 parent 33e4c99 commit c1a7e8c

File tree

15 files changed

+215
-10
lines changed

15 files changed

+215
-10
lines changed

news/2 Fixes/11245.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Warn when using a version of the widget `qgrid` greater than `1.1.1` with the recommendation to downgrade to `1.1.1`.

package.nls.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -474,5 +474,6 @@
474474
"DataScience.loadThirdPartyWidgetScriptsPostEnabled": "Please restart the Kernel when changing the setting 'python.dataScience.widgetScriptSources'.",
475475
"DataScience.enableCDNForWidgetsSetting": "Widgets require us to download supporting files from a 3rd party website. Click <a href='https://command:python.datascience.enableLoadingWidgetScriptsFromThirdPartySource'>here</a> to enable this or click <a href='https://aka.ms/PVSCIPyWidgets'>here</a> for more information. (Error loading {0}:{1}).",
476476
"DataScience.widgetScriptNotFoundOnCDNWidgetMightNotWork": "Unable to load a compatible version of the widget '{0}'. Expected behavior may be affected.",
477-
"DataScience.unhandledMessage": "Unhandled kernel message from a widget: {0} : {1}"
477+
"DataScience.unhandledMessage": "Unhandled kernel message from a widget: {0} : {1}",
478+
"DataScience.qgridWidgetScriptVersionCompatibilityWarning": "Unable to load a compatible version of the widget 'qgrid'. Consider downgrading to version 1.1.1."
478479
}

src/client/common/utils/localize.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -876,6 +876,10 @@ export namespace DataScience {
876876
'DataScience.widgetScriptNotFoundOnCDNWidgetMightNotWork',
877877
"Unable to load a compatible version of the widget '{0}'. Expected behavior may be affected."
878878
);
879+
export const qgridWidgetScriptVersionCompatibilityWarning = localize(
880+
'DataScience.qgridWidgetScriptVersionCompatibilityWarning',
881+
"Unable to load a compatible version of the widget 'qgrid'. Consider downgrading to version 1.1.1."
882+
);
879883
}
880884

881885
export namespace DebugConfigStrings {

src/client/datascience/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@ export enum Telemetry {
290290
ZMQNotSupported = 'DATASCIENCE.ZMQ_NATIVE_BINARIES_NOT_LOADING',
291291
IPyWidgetLoadSuccess = 'DS_INTERNAL.IPYWIDGET_LOAD_SUCCESS',
292292
IPyWidgetLoadFailure = 'DS_INTERNAL.IPYWIDGET_LOAD_FAILURE',
293+
IPyWidgetWidgetVersionNotSupportedLoadFailure = 'DS_INTERNAL.IPYWIDGET_WIDGET_VERSION_NOT_SUPPORTED_LOAD_FAILURE',
293294
IPyWidgetLoadDisabled = 'DS_INTERNAL.IPYWIDGET_LOAD_DISABLED',
294295
HashedIPyWidgetNameUsed = 'DS_INTERNAL.IPYWIDGET_USED_BY_USER',
295296
HashedIPyWidgetNameDiscovered = 'DS_INTERNAL.IPYWIDGET_DISCOVERED',

src/client/datascience/interactive-common/interactiveWindowTypes.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ import {
1010
CommonActionType,
1111
IAddCellAction,
1212
ILoadIPyWidgetClassFailureAction,
13-
LoadIPyWidgetClassLoadAction
13+
LoadIPyWidgetClassLoadAction,
14+
NotifyIPyWidgeWidgetVersionNotSupportedAction
1415
} from '../../../datascience-ui/interactive-common/redux/reducers/types';
1516
import { PythonInterpreter } from '../../interpreter/contracts';
1617
import { NativeKeyboardCommandTelemetry, NativeMouseCommandTelemetry } from '../constants';
@@ -117,7 +118,8 @@ export enum InteractiveWindowMessages {
117118
IPyWidgetLoadSuccess = 'ipywidget_load_success',
118119
IPyWidgetLoadFailure = 'ipywidget_load_failure',
119120
IPyWidgetRenderFailure = 'ipywidget_render_failure',
120-
IPyWidgetUnhandledKernelMessage = 'ipywidget_unhandled_kernel_message'
121+
IPyWidgetUnhandledKernelMessage = 'ipywidget_unhandled_kernel_message',
122+
IPyWidgetWidgetVersionNotSupported = 'ipywidget_widget_version_not_supported'
121123
}
122124

123125
export enum IPyWidgetMessages {
@@ -580,6 +582,7 @@ export class IInteractiveWindowMapping {
580582
public [InteractiveWindowMessages.UpdateDisplayData]: KernelMessage.IUpdateDisplayDataMsg;
581583
public [InteractiveWindowMessages.IPyWidgetLoadSuccess]: LoadIPyWidgetClassLoadAction;
582584
public [InteractiveWindowMessages.IPyWidgetLoadFailure]: ILoadIPyWidgetClassFailureAction;
585+
public [InteractiveWindowMessages.IPyWidgetWidgetVersionNotSupported]: NotifyIPyWidgeWidgetVersionNotSupportedAction;
583586
public [InteractiveWindowMessages.ConvertUriForUseInWebViewRequest]: Uri;
584587
public [InteractiveWindowMessages.ConvertUriForUseInWebViewResponse]: { request: Uri; response: Uri };
585588
public [InteractiveWindowMessages.IPyWidgetRenderFailure]: Error;

src/client/datascience/interactive-common/synchronization.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ const messageWithMessageTypes: MessageMapping<IInteractiveWindowMapping> & Messa
8888
[CommonActionType.FOCUS_INPUT]: MessageType.other,
8989
[CommonActionType.LOAD_IPYWIDGET_CLASS_SUCCESS]: MessageType.other,
9090
[CommonActionType.LOAD_IPYWIDGET_CLASS_FAILURE]: MessageType.other,
91+
[CommonActionType.IPYWIDGET_WIDGET_VERSION_NOT_SUPPORTED]: MessageType.other,
9192
[CommonActionType.IPYWIDGET_RENDER_FAILURE]: MessageType.other,
9293

9394
// Types from InteractiveWindowMessages
@@ -119,6 +120,7 @@ const messageWithMessageTypes: MessageMapping<IInteractiveWindowMapping> & Messa
119120
[InteractiveWindowMessages.IPyWidgetLoadFailure]: MessageType.other,
120121
[InteractiveWindowMessages.IPyWidgetRenderFailure]: MessageType.other,
121122
[InteractiveWindowMessages.IPyWidgetUnhandledKernelMessage]: MessageType.other,
123+
[InteractiveWindowMessages.IPyWidgetWidgetVersionNotSupported]: MessageType.other,
122124
[InteractiveWindowMessages.LoadAllCells]: MessageType.other,
123125
[InteractiveWindowMessages.LoadAllCellsComplete]: MessageType.other,
124126
[InteractiveWindowMessages.LoadOnigasmAssemblyRequest]: MessageType.other,

src/client/datascience/ipywidgets/ipywidgetHandler.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import stripAnsi from 'strip-ansi';
99
import { Event, EventEmitter, Uri } from 'vscode';
1010
import {
1111
ILoadIPyWidgetClassFailureAction,
12-
LoadIPyWidgetClassLoadAction
12+
LoadIPyWidgetClassLoadAction,
13+
NotifyIPyWidgeWidgetVersionNotSupportedAction
1314
} from '../../../datascience-ui/interactive-common/redux/reducers/types';
1415
import { EnableIPyWidgets } from '../../common/experimentGroups';
1516
import { traceError, traceInfo } from '../../common/logger';
@@ -75,6 +76,8 @@ export class IPyWidgetHandler implements IInteractiveWindowListener {
7576
this.sendLoadSucceededTelemetry(payload);
7677
} else if (message === InteractiveWindowMessages.IPyWidgetLoadFailure) {
7778
this.sendLoadFailureTelemetry(payload);
79+
} else if (message === InteractiveWindowMessages.IPyWidgetWidgetVersionNotSupported) {
80+
this.sendUnsupportedWidgetVersionFailureTelemetry(payload);
7881
} else if (message === InteractiveWindowMessages.IPyWidgetRenderFailure) {
7982
this.sendRenderFailureTelemetry(payload);
8083
} else if (message === InteractiveWindowMessages.IPyWidgetUnhandledKernelMessage) {
@@ -111,6 +114,16 @@ export class IPyWidgetHandler implements IInteractiveWindowListener {
111114
// do nothing on failure
112115
}
113116
}
117+
private sendUnsupportedWidgetVersionFailureTelemetry(payload: NotifyIPyWidgeWidgetVersionNotSupportedAction) {
118+
try {
119+
sendTelemetryEvent(Telemetry.IPyWidgetWidgetVersionNotSupportedLoadFailure, 0, {
120+
moduleHash: this.hash(payload.moduleName),
121+
moduleVersion: payload.moduleVersion
122+
});
123+
} catch {
124+
// do nothing on failure
125+
}
126+
}
114127
private sendRenderFailureTelemetry(payload: Error) {
115128
try {
116129
traceError('Error rendering a widget: ', payload);

src/client/telemetry/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1974,6 +1974,10 @@ export interface IEventNamePropertyMapping {
19741974
// Whether we timedout getting the source of the script (fetching script source in extension code).
19751975
timedout: boolean;
19761976
};
1977+
/**
1978+
* Telemetry event sent when an ipywidget version that is not supported is used & we have trapped this and warned the user abou it.
1979+
*/
1980+
[Telemetry.IPyWidgetWidgetVersionNotSupportedLoadFailure]: { moduleHash: string; moduleVersion: string };
19771981
/**
19781982
* Telemetry event sent when an loading of 3rd party ipywidget JS scripts from 3rd party source has been disabled.
19791983
*/

src/datascience-ui/history-react/redux/reducers/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ export const reducerMap: Partial<IInteractiveActionMapping> = {
4343
[CommonActionType.FOCUS_INPUT]: CommonEffects.focusInput,
4444
[CommonActionType.LOAD_IPYWIDGET_CLASS_SUCCESS]: CommonEffects.handleLoadIPyWidgetClassSuccess,
4545
[CommonActionType.LOAD_IPYWIDGET_CLASS_FAILURE]: CommonEffects.handleLoadIPyWidgetClassFailure,
46+
[CommonActionType.IPYWIDGET_WIDGET_VERSION_NOT_SUPPORTED]: CommonEffects.notifyAboutUnsupportedWidgetVersions,
4647
[CommonActionType.IPYWIDGET_RENDER_FAILURE]: CommonEffects.handleIPyWidgetRenderFailure,
4748

4849
// Messages from the webview (some are ignored)

src/datascience-ui/interactive-common/redux/reducers/commonEffects.ts

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ import {
1818
CommonReducerArg,
1919
ILoadIPyWidgetClassFailureAction,
2020
IOpenSettingsAction,
21-
LoadIPyWidgetClassLoadAction
21+
LoadIPyWidgetClassLoadAction,
22+
NotifyIPyWidgeWidgetVersionNotSupportedAction
2223
} from './types';
2324

2425
export namespace CommonEffects {
@@ -258,6 +259,42 @@ export namespace CommonEffects {
258259
return arg.prevState;
259260
}
260261
}
262+
export function notifyAboutUnsupportedWidgetVersions(
263+
arg: CommonReducerArg<CommonActionType, NotifyIPyWidgeWidgetVersionNotSupportedAction>
264+
): IMainState {
265+
// Find the first currently executing cell and add an error to its output
266+
let index = arg.prevState.cellVMs.findIndex((c) => c.cell.state === CellState.executing);
267+
268+
// If there isn't one, then find the latest that matches the current execution count.
269+
if (index < 0) {
270+
index = arg.prevState.cellVMs.findIndex(
271+
(c) => c.cell.data.execution_count === arg.prevState.currentExecutionCount
272+
);
273+
}
274+
if (index >= 0 && arg.prevState.cellVMs[index].cell.data.cell_type === 'code') {
275+
const newVMs = [...arg.prevState.cellVMs];
276+
const current = arg.prevState.cellVMs[index];
277+
278+
const errorMessage = getLocString(
279+
'DataScience.qgridWidgetScriptVersionCompatibilityWarning',
280+
"Unable to load a compatible version of the widget 'qgrid'. Consider downgrading to version 1.1.1."
281+
);
282+
newVMs[index] = Helpers.asCellViewModel({
283+
...current,
284+
uiSideError: errorMessage
285+
});
286+
287+
// Make sure to tell the extension so it can log telemetry.
288+
postActionToExtension(arg, InteractiveWindowMessages.IPyWidgetWidgetVersionNotSupported, arg.payload.data);
289+
290+
return {
291+
...arg.prevState,
292+
cellVMs: newVMs
293+
};
294+
} else {
295+
return arg.prevState;
296+
}
297+
}
261298
export function handleIPyWidgetRenderFailure(arg: CommonReducerArg<CommonActionType, Error>): IMainState {
262299
// Make sure to tell the extension so it can log telemetry.
263300
postActionToExtension(arg, InteractiveWindowMessages.IPyWidgetRenderFailure, arg.payload.data);

0 commit comments

Comments
 (0)