Add tracks for plugin installation and activation (#37261)

* Add @woocommerce/tracks to @woocommerce/data dependencies

* Add tracks for plugin actions and handle plugin error properly

* Add changelog

* Add doc

* Update doc
This commit is contained in:
Chi-Hsuan Huang 2023-03-20 10:38:30 +08:00 committed by GitHub
parent c5564a15c1
commit 7b10baff00
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 48 additions and 30 deletions

View File

@ -0,0 +1,4 @@
Significance: minor
Type: enhancement
Add tracks for plugin actions and handle plugin error properly

View File

@ -28,6 +28,7 @@
"dependencies": {
"@woocommerce/date": "workspace:*",
"@woocommerce/navigation": "workspace:*",
"@woocommerce/tracks": "workspace:*",
"@wordpress/api-fetch": "wp-6.0",
"@wordpress/compose": "wp-6.0",
"@wordpress/core-data": "wp-6.0",

View File

@ -9,6 +9,7 @@ import {
import { _n, sprintf } from '@wordpress/i18n';
import { DispatchFromMap } from '@automattic/data-stores';
import { controls } from '@wordpress/data';
import { recordEvent } from '@woocommerce/tracks';
/**
* Internal dependencies
@ -49,21 +50,22 @@ const isPluginResponseError = (
typeof error === 'object' && error !== null && plugins[ 0 ] in error;
const formatErrorMessage = (
pluginErrors: PluginResponseErrors,
actionType = 'install'
actionType: 'install' | 'activate' = 'install',
plugins: Partial< PluginNames >[],
rawErrorMessage: string
) => {
return sprintf(
/* translators: %(actionType): install or activate (the plugin). %(pluginName): a plugin slug (e.g. woocommerce-services). %(error): a single error message or in plural a comma separated error message list.*/
_n(
'Could not %(actionType)s %(pluginName)s plugin, %(error)s',
'Could not %(actionType)s the following plugins: %(pluginName)s with these Errors: %(error)s',
Object.keys( pluginErrors ).length || 1,
Object.keys( plugins ).length || 1,
'woocommerce'
),
{
actionType,
pluginName: Object.keys( pluginErrors ).join( ', ' ),
error: Object.values( pluginErrors ).join( ', \n' ),
pluginName: plugins.join( ', ' ),
error: rawErrorMessage,
}
);
};
@ -174,35 +176,42 @@ export function setRecommendedPlugins(
}
function* handlePluginAPIError(
actionType: string,
actionType: 'install' | 'activate',
plugins: Partial< PluginNames >[],
error: unknown
) {
yield setError( 'installPlugins', error );
let rawErrorMessage;
let pluginResponseError = error;
if (
( error instanceof Error || isRestApiError( error ) ) &&
plugins[ 0 ]
) {
pluginResponseError = {
[ plugins[ 0 ] ]: [ error.message ],
};
}
if ( isPluginResponseError( plugins, pluginResponseError ) ) {
throw new PluginError(
formatErrorMessage( pluginResponseError, actionType ),
pluginResponseError
);
if ( isPluginResponseError( plugins, error ) ) {
// Backend error messages are in the form of { plugin-slug: [ error messages ] }.
rawErrorMessage = Object.values( error ).join( ', \n' );
} else {
throw new PluginError(
`Unexpected Plugin Error: ${ JSON.stringify(
pluginResponseError
) }`,
pluginResponseError
);
// Other error such as API connection errors.
rawErrorMessage =
isRestApiError( error ) || error instanceof Error
? error.message
: JSON.stringify( error );
}
// Track the error.
switch ( actionType ) {
case 'install':
recordEvent( 'install_plugins_error', {
plugins: plugins.join( ', ' ),
message: rawErrorMessage,
} );
break;
case 'activate':
recordEvent( 'activate_plugins_error', {
plugins: plugins.join( ', ' ),
message: rawErrorMessage,
} );
}
throw new PluginError(
formatErrorMessage( actionType, plugins, rawErrorMessage ),
error
);
}
// Action Creator Generators
@ -225,6 +234,7 @@ export function* installPlugins( plugins: Partial< PluginNames >[] ) {
return results;
} catch ( error ) {
yield setError( 'installPlugins', error );
yield handlePluginAPIError( 'install', plugins, error );
} finally {
yield setIsRequesting( 'installPlugins', false );
@ -251,6 +261,7 @@ export function* activatePlugins( plugins: Partial< PluginNames >[] ) {
return results;
} catch ( error ) {
yield setError( 'activatePlugins', error );
yield handlePluginAPIError( 'activate', plugins, error );
} finally {
yield setIsRequesting( 'activatePlugins', false );
@ -305,7 +316,7 @@ export function* connectToJetpack(
}
export function* installJetpackAndConnect(
errorAction: ( errorMesage: string ) => void,
errorAction: ( errorMessage: string ) => void,
getAdminLink: ( endpoint: string ) => string
) {
try {
@ -329,7 +340,7 @@ export function* installJetpackAndConnect(
export function* connectToJetpackWithFailureRedirect(
failureRedirect: string,
errorAction: ( errorMesage: string ) => void,
errorAction: ( errorMessage: string ) => void,
getAdminLink: ( endpoint: string ) => string
) {
try {

View File

@ -608,6 +608,7 @@ importers:
'@woocommerce/date': workspace:*
'@woocommerce/eslint-plugin': workspace:*
'@woocommerce/navigation': workspace:*
'@woocommerce/tracks': workspace:*
'@wordpress/api-fetch': wp-6.0
'@wordpress/compose': wp-6.0
'@wordpress/core-data': wp-6.0
@ -635,6 +636,7 @@ importers:
dependencies:
'@woocommerce/date': link:../date
'@woocommerce/navigation': link:../navigation
'@woocommerce/tracks': link:../tracks
'@wordpress/api-fetch': 6.3.1
'@wordpress/compose': 5.4.1_react@17.0.2
'@wordpress/core-data': 4.4.5_react@17.0.2