diff --git a/src/client/handlers/VaultsSecretsMkdir.ts b/src/client/handlers/VaultsSecretsMkdir.ts index 0249db33f..9284c74e0 100644 --- a/src/client/handlers/VaultsSecretsMkdir.ts +++ b/src/client/handlers/VaultsSecretsMkdir.ts @@ -48,9 +48,25 @@ class VaultsSecretsMkdir extends DuplexHandler< yield await vaultManager.withVaults( [vaultId], async (vault) => { - return await vaultOps.mkdir(vault, dirName, { - recursive: metadata?.options?.recursive, - }); + try { + await vaultOps.mkdir(vault, dirName, { + recursive: metadata?.options?.recursive, + }); + return { type: 'success', success: true }; + } catch (e) { + if ( + e instanceof vaultsErrors.ErrorVaultsRecursive || + e instanceof vaultsErrors.ErrorSecretsSecretDefined + ) { + return { + type: 'error', + code: e.cause.code, + reason: dirName, + }; + } else { + throw e; + } + } }, tran, ); diff --git a/src/client/types.ts b/src/client/types.ts index 32acc7046..e79e62c0b 100644 --- a/src/client/types.ts +++ b/src/client/types.ts @@ -207,7 +207,7 @@ type SuccessMessage = { type ErrorMessage = { type: 'error'; - code: string; + code?: string | number; reason?: string; data?: JSONObject; }; diff --git a/src/vaults/VaultOps.ts b/src/vaults/VaultOps.ts index ea559ab1d..cb98f5e66 100644 --- a/src/vaults/VaultOps.ts +++ b/src/vaults/VaultOps.ts @@ -4,7 +4,6 @@ import type Logger from '@matrixai/logger'; import type { Vault } from './Vault'; import type { Stat } from 'encryptedfs'; -import type { SuccessOrErrorMessage } from '../client/types'; import path from 'path'; import * as vaultsErrors from './errors'; import * as vaultsUtils from './utils'; @@ -174,7 +173,7 @@ async function mkdir( dirPath: string, fileOptions?: FileOptions, logger?: Logger, -): Promise { +): Promise { const recursive = fileOptions?.recursive ?? false; // Technically, writing an empty directory won't make a commit, and doesn't // need a write resource as git doesn't track empty directories. It is @@ -184,22 +183,19 @@ async function mkdir( await efs.mkdir(dirPath, fileOptions); logger?.info(`Created secret directory at '${dirPath}'`); }); - return { type: 'success', success: true }; } catch (e) { logger?.error(`Failed to create directory '${dirPath}'. Reason: ${e.code}`); if (e.code === 'ENOENT' && !recursive) { - return { - type: 'error', - code: e.code, - reason: dirPath, - }; + throw new vaultsErrors.ErrorVaultsRecursive( + `Could not create direcotry '${dirPath}' without recursive option`, + { cause: e }, + ); } if (e.code === 'EEXIST') { - return { - type: 'error', - code: e.code, - reason: dirPath, - }; + throw new vaultsErrors.ErrorSecretsSecretDefined( + `${dirPath} already exists`, + { cause: e }, + ); } throw e; } diff --git a/tests/client/handlers/vaults.test.ts b/tests/client/handlers/vaults.test.ts index 26f5efba8..18a64fa0c 100644 --- a/tests/client/handlers/vaults.test.ts +++ b/tests/client/handlers/vaults.test.ts @@ -1338,6 +1338,27 @@ describe('vaultsSecretsMkdir', () => { recursive: true, }); }); + test('fails with invalid vault name', async () => { + const vaultName = 'test-vault'; + const dirName = 'dir'; + const response = await rpcClient.methods.vaultsSecretsMkdir(); + const writer = response.writable.getWriter(); + await writer.write({ + nameOrId: vaultName, + dirName: dirName, + }); + await writer.close(); + const consumeP = async () => { + try { + for await (const _ of response.readable); + } catch (e) { + throw e.cause; + } + }; + await expect(consumeP()).rejects.toThrow( + vaultsErrors.ErrorVaultsVaultUndefined, + ); + }); test('makes a directory', async () => { const vaultName = 'test-vault'; const vaultId = await vaultManager.createVault(vaultName); diff --git a/tests/vaults/VaultOps/mkdir.test.ts b/tests/vaults/VaultOps/mkdir.test.ts index 9e0e0c0a1..b8869da44 100644 --- a/tests/vaults/VaultOps/mkdir.test.ts +++ b/tests/vaults/VaultOps/mkdir.test.ts @@ -12,6 +12,7 @@ import { DB } from '@matrixai/db'; import VaultInternal from '@/vaults/VaultInternal'; import * as vaultOps from '@/vaults/VaultOps'; import * as vaultsUtils from '@/vaults/utils'; +import * as vaultsErrors from '@/vaults/errors'; import * as keysUtils from '@/keys/utils'; import * as testNodesUtils from '../../nodes/utils'; import * as testVaultsUtils from '../utils'; @@ -89,44 +90,39 @@ describe('mkdir', () => { }); test('can create directory', async () => { - const response = await vaultOps.mkdir(vault, dirName); - expect(response.type).toEqual('success'); + await vaultOps.mkdir(vault, dirName); await testVaultsUtils.expectDirExists(vault, dirName); }); test('can create recursive directory', async () => { const dirPath = path.join(dirName, dirName); - const response = await vaultOps.mkdir(vault, dirPath, { + await vaultOps.mkdir(vault, dirPath, { recursive: true, }); - expect(response.type).toEqual('success'); await testVaultsUtils.expectDirExists(vault, dirPath); }); test('creating directories fails without recursive', async () => { const dirPath = path.join(dirName, dirName); - const response = await vaultOps.mkdir(vault, dirPath); - expect(response.type).toEqual('error'); - const error = response as ErrorMessage; - expect(error.code).toEqual('ENOENT'); + await expect(vaultOps.mkdir(vault, dirPath)).rejects.toThrow( + vaultsErrors.ErrorVaultsRecursive, + ); await testVaultsUtils.expectDirExistsNot(vault, dirPath); }); test('creating existing directory should fail', async () => { await testVaultsUtils.mkdir(vault, dirName); - const response = await vaultOps.mkdir(vault, dirName); - expect(response.type).toEqual('error'); - const error = response as ErrorMessage; - expect(error.code).toEqual('EEXIST'); + await expect(vaultOps.mkdir(vault, dirName)).rejects.toThrow( + vaultsErrors.ErrorSecretsSecretDefined, + ); + await testVaultsUtils.expectDirExists(vault, dirName); }); test('creating existing secret should fail', async () => { await testVaultsUtils.writeSecret(vault, secretName, secretContent); - const response = await vaultOps.mkdir(vault, secretName); - expect(response.type).toEqual('error'); - const error = response as ErrorMessage; - expect(error.code).toEqual('EEXIST'); + await expect(vaultOps.mkdir(vault, secretName)).rejects.toThrow( + vaultsErrors.ErrorSecretsSecretDefined, + ); await testVaultsUtils.expectSecret(vault, secretName, secretContent); }); test('can create a hidden directory', async () => { - const response = await vaultOps.mkdir(vault, dirNameHidden); - expect(response.type).toEqual('success'); + await vaultOps.mkdir(vault, dirNameHidden); await testVaultsUtils.expectDirExists(vault, dirNameHidden); }); });