diff --git a/messages/delete_sandbox.md b/messages/delete_sandbox.md index bf24b3f7..27fd4331 100644 --- a/messages/delete_sandbox.md +++ b/messages/delete_sandbox.md @@ -54,3 +54,7 @@ Ensure the CLI has authenticated with the sandbox's production org. # error.missingUsername Unable to determine the username of the org to delete. Specify the username with the --target-org | -o flag. + +# error.insufficientAccess + +You don't have permission to delete this sandbox. Ask your Salesforce admin to grant you the "Manage Sandboxes" system permission on your profile or a permission set in the production org. diff --git a/src/commands/org/delete/sandbox.ts b/src/commands/org/delete/sandbox.ts index 971f3aaa..a1918451 100644 --- a/src/commands/org/delete/sandbox.ts +++ b/src/commands/org/delete/sandbox.ts @@ -84,6 +84,12 @@ export default class DeleteSandbox extends SfCommand { this.logSuccess(messages.getMessage('success.Idempotent', [username])); } else if (e instanceof Error && e.name === 'SandboxNotFound') { this.logSuccess(messages.getMessage('success.Idempotent', [username])); + } else if ( + e instanceof Error && + 'errorCode' in e && + (e as { errorCode: string }).errorCode === 'INSUFFICIENT_ACCESS_OR_READONLY' + ) { + throw messages.createError('error.insufficientAccess'); } else { throw e; } diff --git a/test/unit/org/delete.test.ts b/test/unit/org/delete.test.ts index 622312c5..9403d604 100644 --- a/test/unit/org/delete.test.ts +++ b/test/unit/org/delete.test.ts @@ -137,6 +137,23 @@ describe('org delete', () => { JSON.stringify(sfCommandUxStubs.logSuccess.getCalls().flatMap((call) => call.args)) ).to.deep.include(sbxOrgMessages.getMessage('success.Idempotent', [testOrg.username])); }); + + it('will throw a clean SfError when the user lacks Manage Sandboxes permission', async () => { + $$.SANDBOX.stub(SandboxAccessor.prototype, 'hasFile').resolves(true); + orgDeleteStub.restore(); + const insufficientAccessError = Object.assign(new Error('INSUFFICIENT_ACCESS_OR_READONLY'), { + errorCode: 'INSUFFICIENT_ACCESS_OR_READONLY', + }); + $$.SANDBOX.stub(Org.prototype, 'delete').throws(insufficientAccessError); + try { + await DeleteSandbox.run(['--no-prompt', '--target-org', testOrg.username]); + expect.fail('should have thrown InsufficientAccessError'); + } catch (e) { + const err = e as SfError; + expect(err.name).to.equal('InsufficientAccessError'); + expect(err.message).to.equal(sbxOrgMessages.getMessage('error.insufficientAccess')); + } + }); }); describe('scratch', () => {