Skip to content

Commit

Permalink
feat(snapshot): enhance snapshot error messages (#431)
Browse files Browse the repository at this point in the history
  • Loading branch information
y-lakhdar authored Aug 17, 2021
1 parent 2f2f986 commit 46947b3
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 44 deletions.
26 changes: 4 additions & 22 deletions packages/cli/src/commands/org/config/monitor.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import {ResourceSnapshotsReportModel} from '@coveord/platform-client';
import {flags, Command} from '@oclif/command';
import {cli} from 'cli-ux';
import dedent from 'ts-dedent';
import {
buildAnalyticsFailureHook,
buildAnalyticsSuccessHook,
Expand All @@ -17,10 +16,10 @@ import {
waitFlag,
getTargetOrg,
handleSnapshotError,
handleReportWithErrors,
} from '../../../lib/snapshot/snapshotCommon';
import {SnapshotFactory} from '../../../lib/snapshot/snapshotFactory';
import {SnapshotReporter} from '../../../lib/snapshot/snapshotReporter';
import {SnapshotUrlBuilder} from '../../../lib/snapshot/snapshotUrlBuilder';

export default class Monitor extends Command {
public static description = 'Monitor a Snapshot operation';
Expand Down Expand Up @@ -77,29 +76,12 @@ export default class Monitor extends Command {
reporter: SnapshotReporter
) {
if (!reporter.isSuccessReport()) {
await this.displaySnapshotError(snapshot, reporter);
const cfg = await this.configuration.get();
cli.log(ReportViewerStyles.error(reporter.resultCode));
await handleReportWithErrors(snapshot, cfg);
}
}

// TODO: CDX-533: use Custom error instead
private async displaySnapshotError(
snapshot: Snapshot,
reporter: SnapshotReporter
) {
cli.log(ReportViewerStyles.error(reporter.resultCode));
cli.log();
const cfg = await this.configuration.get();
const urlBuilder = new SnapshotUrlBuilder(cfg);
const snapshotUrl = urlBuilder.getSnapshotPage(snapshot);

cli.error(
dedent`Invalid snapshot - ${snapshot.latestReport.resultCode}.
You can also use this link to view the snapshot in the Coveo Admin Console:
${snapshotUrl}`
);
}

private printHeader() {
const {args} = this.parse(Monitor);
const snapshotId = args.snapshotId;
Expand Down
70 changes: 60 additions & 10 deletions packages/cli/src/lib/errors/snapshotErrors.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,48 @@
import {blueBright} from 'chalk';
import {cli} from 'cli-ux';
import dedent from 'ts-dedent';
import {Configuration} from '../config/config';
import {Snapshot} from '../snapshot/snapshot';
import {SnapshotUrlBuilder} from '../snapshot/snapshotUrlBuilder';

export class SnapshotOperationTimeoutError extends Error {
public constructor(public snapshot: Snapshot) {
enum SeverityLevel {
Info = 'info',
Warn = 'warn',
Error = 'error',
}

interface IDetailedReportable extends SnapshotError {
snapshot: Snapshot;
level: SeverityLevel;
projectPath?: string;
}

function trySavingDetailedReport(error: IDetailedReportable) {
if (error.projectPath) {
const reportPath = error.snapshot.saveDetailedReport(error.projectPath);
error.message += dedent`\n\n
Detailed report saved at ${reportPath}`;
}
}

export class SnapshotError extends Error {
public constructor(public level: SeverityLevel) {
super();
}

public print() {
cli.log();
cli[this.level]('\n' + this.message);
}
}

export class SnapshotOperationTimeoutError
extends SnapshotError
implements IDetailedReportable
{
public name = 'Snapshot Operation Timeout Error';
public constructor(public snapshot: Snapshot) {
super(SeverityLevel.Info);
this.message = dedent`${
snapshot.latestReport.type
} operation is taking a long time to complete.
Expand All @@ -16,34 +52,48 @@ export class SnapshotOperationTimeoutError extends Error {
}
}

export class SnapshotSynchronizationError extends Error {
public constructor(public snapshot: Snapshot, public cfg: Configuration) {
super();
export class SnapshotSynchronizationError
extends SnapshotError
implements IDetailedReportable
{
public name = 'Snapshot Synchronization Error';
public constructor(
public snapshot: Snapshot,
public cfg: Configuration,
public projectPath?: string
) {
super(SeverityLevel.Warn);
const urlBuilder = new SnapshotUrlBuilder(cfg);
const synchronizationPlanUrl = urlBuilder.getSynchronizationPage(snapshot);

this.message = dedent`
Some conflicts were detected while comparing changes between the snapshot and the target organization.
Click on the URL below to synchronize your snapshot with your organization before running another push command.
${synchronizationPlanUrl}`;

trySavingDetailedReport(this);
}
}

export class SnapshotGenericError extends Error {
export class SnapshotGenericError
extends SnapshotError
implements IDetailedReportable
{
public name = 'Snapshot Error';
public constructor(
public snapshot: Snapshot,
public cfg: Configuration,
public pathToReport: string
public projectPath?: string
) {
super();
super(SeverityLevel.Error);
const report = snapshot.latestReport;
const urlBuilder = new SnapshotUrlBuilder(cfg);
const snapshotUrl = urlBuilder.getSnapshotPage(snapshot);

this.message = dedent`Invalid snapshot - ${report.resultCode}.
Detailed report saved at ${pathToReport}.
You can also use this link to view the snapshot in the Coveo Admin Console
${snapshotUrl}`;

trySavingDetailedReport(this);
}
}
22 changes: 10 additions & 12 deletions packages/cli/src/lib/snapshot/snapshotCommon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import {Snapshot, WaitUntilDoneOptions} from './snapshot';
import {red, green} from 'chalk';
import {normalize} from 'path';
import {Config, Configuration} from '../config/config';
import {SnapshotOperationTimeoutError} from '../errors';
import {
SnapshotError,
SnapshotGenericError,
SnapshotSynchronizationError,
} from '../errors/snapshotErrors';
Expand Down Expand Up @@ -69,24 +69,22 @@ export function cleanupProject(projectPath: string) {
export async function handleReportWithErrors(
snapshot: Snapshot,
cfg: Configuration,
projectPath: string
projectPath?: string
) {
if (snapshot.requiresSynchronization()) {
throw new SnapshotSynchronizationError(snapshot, cfg);
throw new SnapshotSynchronizationError(snapshot, cfg, projectPath);
}

const pathToReport = snapshot.saveDetailedReport(projectPath);
throw new SnapshotGenericError(snapshot, cfg, pathToReport);
throw new SnapshotGenericError(snapshot, cfg, projectPath);
}

export function handleSnapshotError(err?: Error) {
if (err instanceof SnapshotOperationTimeoutError) {
cli.action.stop('Incomplete');
cli.log(err.message);
} else if (err instanceof SnapshotSynchronizationError) {
cli.warn(err.message);
} else if (err instanceof SnapshotGenericError) {
cli.error(err.message);
if (cli.action.running) {
cli.action.stop(err?.name);
}

if (err instanceof SnapshotError) {
err.print();
} else {
throw err;
}
Expand Down

0 comments on commit 46947b3

Please sign in to comment.