diff --git a/src/hooks/sync-sites/use-sync-push.ts b/src/hooks/sync-sites/use-sync-push.ts index c2c3e07e77..9b809501e8 100644 --- a/src/hooks/sync-sites/use-sync-push.ts +++ b/src/hooks/sync-sites/use-sync-push.ts @@ -139,8 +139,11 @@ export function useSyncPush( { status: pushStatesProgressInfo.failed, } ); getIpcApi().showErrorMessageBox( { - title: sprintf( __( 'Error exporting site to %s' ), connectedSite.name ), - message: __( 'Studio was unable to export the site.' ), + title: sprintf( __( 'Error pushing to %s' ), connectedSite.name ), + message: __( + 'An error occurred while pushing the site. If this problem persists, please contact support.' + ), + error, } ); return; } diff --git a/src/hooks/use-chat-context.tsx b/src/hooks/use-chat-context.tsx index 58b4ef6542..fbca2cc9d6 100644 --- a/src/hooks/use-chat-context.tsx +++ b/src/hooks/use-chat-context.tsx @@ -53,7 +53,6 @@ const parseWpCliOutput = ( stdout: string, defaultValue: string[] ): string[] => const data = JSON.parse( stdout ); return data?.map( ( item: { name: string } ) => item.name ) || []; } catch ( error ) { - console.error( error, stdout ); Sentry.captureException( error, { extra: { stdout }, } ); diff --git a/src/lib/import-export/export/export-database.ts b/src/lib/import-export/export/export-database.ts index 4db209a969..ddea88d337 100644 --- a/src/lib/import-export/export/export-database.ts +++ b/src/lib/import-export/export/export-database.ts @@ -47,7 +47,7 @@ export async function exportDatabaseToMultipleFiles( } const tablesResult = await server.executeWpCliCommand( - `sqlite tables --format=csv --require=/tmp/sqlite-command/command.php` + `sqlite tables --format=json --require=/tmp/sqlite-command/command.php` ); if ( tablesResult.stderr ) { throw new Error( `Database export failed: ${ tablesResult.stderr }` ); @@ -55,7 +55,17 @@ export async function exportDatabaseToMultipleFiles( if ( tablesResult.exitCode ) { throw new Error( 'Database export failed' ); } - const tables = tablesResult.stdout.split( ',' ); + + let tables; + + try { + tables = JSON.parse( tablesResult.stdout ); + } catch ( error ) { + console.error( + `Could not get list of database tables. The WP CLI output: ${ tablesResult.stdout }` + ); + throw new Error( 'Could not get list of database tables to export.' ); + } const tmpFiles: string[] = []; diff --git a/src/lib/import-export/export/exporters/default-exporter.ts b/src/lib/import-export/export/exporters/default-exporter.ts index 2ab339e54d..6e3eff2c2f 100644 --- a/src/lib/import-export/export/exporters/default-exporter.ts +++ b/src/lib/import-export/export/exporters/default-exporter.ts @@ -273,10 +273,19 @@ export class DefaultExporter extends EventEmitter implements Exporter { if ( stderr ) { console.error( `Could not get information about plugins: ${ stderr }` ); - return []; + throw new Error( + 'Could not get information about installed plugins to create meta.json file.' + ); } - return JSON.parse( stdout ); + try { + return JSON.parse( stdout ); + } catch ( error ) { + console.error( `Could not parse plugins list. The WP CLI output: ${ stdout }` ); + throw new Error( + 'Could not parse information about installed plugins to create meta.json file.' + ); + } } private async getSiteThemes( site_id: string ) { @@ -292,9 +301,18 @@ export class DefaultExporter extends EventEmitter implements Exporter { if ( stderr ) { console.error( `Could not get information about themes: ${ stderr }` ); - return []; + throw new Error( + 'Could not get information about installed themes to create meta.json file.' + ); } - return JSON.parse( stdout ); + try { + return JSON.parse( stdout ); + } catch ( error ) { + console.error( `Could not parse themes list. The WP CLI output: ${ stdout }` ); + throw new Error( + 'Could not parse information about installed themes to create meta.json file.' + ); + } } } diff --git a/src/lib/import-export/tests/export/exporters/default-exporter.test.ts b/src/lib/import-export/tests/export/exporters/default-exporter.test.ts index 2be3b60449..948fcf2ee3 100644 --- a/src/lib/import-export/tests/export/exporters/default-exporter.test.ts +++ b/src/lib/import-export/tests/export/exporters/default-exporter.test.ts @@ -116,7 +116,7 @@ describe( 'DefaultExporter', () => { case /theme list/.test( command ): return { stdout: '[{"name":"twentytwentyfour","status":"active","version":"1.0"}]' }; case /tables/.test( command ): - return { stdout: defaultTableNames.join( ',' ) }; + return { stdout: JSON.stringify( defaultTableNames ) }; default: return { stderr: null }; } @@ -323,7 +323,7 @@ describe( 'DefaultExporter', () => { expect( canHandle ).toBe( false ); } ); - it( 'should not fail when can not get plugin or theme details', async () => { + it( 'should fail when can not get plugin or theme details', async () => { ( SiteServer.get as jest.Mock ).mockReturnValue( { details: { path: '/path/to/site' }, executeWpCliCommand: jest.fn( function ( command: string ) { @@ -338,10 +338,9 @@ describe( 'DefaultExporter', () => { } ); const exporter = new DefaultExporter( mockOptions ); - await exporter.export(); - expect( mockArchiver.file ).toHaveBeenCalledWith( '/tmp/studio_export_123/meta.json', { - name: 'meta.json', - } ); + await expect( exporter.export() ).rejects.toThrow( + 'Could not get information about installed plugins to create meta.json file.' + ); } ); } );