Skip to content

Commit b1ac18c

Browse files
error handling
Signed-off-by: Elizabeth Healy <[email protected]>
1 parent 34ac145 commit b1ac18c

File tree

2 files changed

+77
-6
lines changed

2 files changed

+77
-6
lines changed

lib/src/access/access-rpc.ts

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,15 @@ import {
66
noteInvalidPublicKey,
77
OriginAllowList,
88
} from '../access.js';
9-
109
import { type AuthProvider } from '../auth/auth.js';
11-
import { ConfigurationError, NetworkError } from '../errors.js';
10+
import {
11+
ConfigurationError,
12+
InvalidFileError,
13+
NetworkError,
14+
PermissionDeniedError,
15+
ServiceError,
16+
UnauthenticatedError,
17+
} from '../errors.js';
1218
import { PlatformClient } from '../platform.js';
1319
import { RewrapResponse } from '../platform/kas/kas_pb.js';
1420
import { ListKeyAccessServersResponse } from '../platform/policy/kasregistry/key_access_server_registry_pb.js';
@@ -19,6 +25,7 @@ import {
1925
validateSecureUrl,
2026
} from '../utils.js';
2127
import { X_REWRAP_ADDITIONAL_CONTEXT } from './constants.js';
28+
import { ConnectError, Code } from '@connectrpc/connect';
2229

2330
/**
2431
* Get a rewrapped access key to the document, if possible
@@ -42,11 +49,70 @@ export async function fetchWrappedKey(
4249
[X_REWRAP_ADDITIONAL_CONTEXT]: rewrapAdditionalContextHeader,
4350
};
4451
}
52+
let response: RewrapResponse;
4553
try {
46-
return await platform.v1.access.rewrap({ signedRequestToken }, options);
54+
response = await platform.v1.access.rewrap({ signedRequestToken }, options);
4755
} catch (e) {
48-
throw new NetworkError(`[${platformUrl}] [Rewrap] ${extractRpcErrorMessage(e)}`);
56+
handleRpcRewrapError(e, platformUrl);
57+
}
58+
return response;
59+
}
60+
61+
function codeName(code: Code): string {
62+
return Code[code];
63+
}
64+
65+
export function handleRpcRewrapError(e: unknown, platformUrl: string): never {
66+
if (e instanceof ConnectError) {
67+
console.log('Error is a ConnectError with code:', e.code);
68+
switch (e.code) {
69+
case Code.InvalidArgument: // 400 Bad Request
70+
throw new InvalidFileError(`400 for [${platformUrl}]: rewrap bad request [${e.message}]`);
71+
case Code.PermissionDenied: // 403 Forbidden
72+
throw new PermissionDeniedError(`403 for [${platformUrl}]; rewrap permission denied`);
73+
case Code.Unauthenticated: // 401 Unauthorized
74+
throw new UnauthenticatedError(`401 for [${platformUrl}]; rewrap auth failure`);
75+
case Code.Internal ||
76+
Code.Unimplemented ||
77+
Code.DataLoss ||
78+
Code.Unknown ||
79+
Code.DeadlineExceeded ||
80+
Code.Unavailable: // >=500 Server Error
81+
throw new ServiceError(
82+
`${e.code} for [${platformUrl}]: rewrap failure due to service error [${e.message}]`
83+
);
84+
default:
85+
throw new NetworkError(`[${platformUrl}] [Rewrap] ${e.message}`);
86+
}
87+
}
88+
throw new NetworkError(`[${platformUrl}] [Rewrap] ${extractRpcErrorMessage(e)}`);
89+
}
90+
91+
export function handleRpcRewrapErrorString(e: string, platformUrl: string): never {
92+
if (e.includes(codeName(Code.InvalidArgument))) {
93+
// 400 Bad Request
94+
throw new InvalidFileError(`400 for [${platformUrl}]: rewrap bad request [${e}]`);
95+
}
96+
if (e.includes(codeName(Code.PermissionDenied))) {
97+
// 403 Forbidden
98+
throw new PermissionDeniedError(`403 for [${platformUrl}]; rewrap permission denied`);
99+
}
100+
if (e.includes(codeName(Code.Unauthenticated))) {
101+
// 401 Unauthorized
102+
throw new UnauthenticatedError(`401 for [${platformUrl}]; rewrap auth failure`);
103+
}
104+
if (
105+
e.includes(codeName(Code.Internal)) ||
106+
e.includes(codeName(Code.Unimplemented)) ||
107+
e.includes(codeName(Code.DataLoss)) ||
108+
e.includes(codeName(Code.Unknown)) ||
109+
e.includes(codeName(Code.DeadlineExceeded)) ||
110+
e.includes(codeName(Code.Unavailable))
111+
) {
112+
// >=500
113+
throw new ServiceError(`500+ [${platformUrl}]: rewrap failure due to service error [${e}]`);
49114
}
115+
throw new NetworkError(`[${platformUrl}] [Rewrap] ${e}}`);
50116
}
51117

52118
export async function fetchKeyAccessServers(

lib/tdf3/src/tdf.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
UnsignedRewrapRequest_WithKeyAccessObjectSchema,
1818
} from '../../src/platform/kas/kas_pb.js';
1919
import { type AuthProvider, reqSignature } from '../../src/auth/auth.js';
20+
import { handleRpcRewrapErrorString } from '../../src/access/access-rpc.js';
2021
import { allPool, anyPool } from '../../src/concurrency.js';
2122
import { base64, hex } from '../../src/encodings/index.js';
2223
import {
@@ -63,7 +64,11 @@ import { ZipReader, ZipWriter, keyMerge, concatUint8, buffToString } from './uti
6364
import { CentralDirectory } from './utils/zip-reader.js';
6465
import { ztdfSalt } from './crypto/salt.js';
6566
import { Payload } from './models/payload.js';
66-
import { getRequiredObligationFQNs, upgradeRewrapResponseV1 } from '../../src/utils.js';
67+
import {
68+
getRequiredObligationFQNs,
69+
upgradeRewrapResponseV1,
70+
getPlatformUrlFromKasEndpoint,
71+
} from '../../src/utils.js';
6772

6873
// TODO: input validation on manifest JSON
6974
const DEFAULT_SEGMENT_SIZE = 1024 * 1024;
@@ -884,7 +889,7 @@ async function unwrapKey({
884889

885890
case 'error': {
886891
const errorMessage = result.result.value;
887-
throw new DecryptError(`KAS rewrap failed: ${errorMessage}`);
892+
handleRpcRewrapErrorString(errorMessage, getPlatformUrlFromKasEndpoint(url));
888893
}
889894

890895
default: {

0 commit comments

Comments
 (0)