|
1 | 1 | // Copyright (c) Mysten Labs, Inc. |
2 | 2 | // SPDX-License-Identifier: Apache-2.0 |
3 | 3 |
|
4 | | -import type { CoreClientOptions, SuiClientTypes } from '../client/index.js'; |
5 | | -import { CoreClient, formatMoveAbortMessage, SimulationError } from '../client/index.js'; |
| 4 | +import type { CoreClientOptions, ObjectErrorCode, SuiClientTypes } from '../client/index.js'; |
| 5 | +import { |
| 6 | + CoreClient, |
| 7 | + formatMoveAbortMessage, |
| 8 | + ObjectError, |
| 9 | + SimulationError, |
| 10 | + SuiClientError, |
| 11 | +} from '../client/index.js'; |
6 | 12 | import type { SuiGrpcClient } from './client.js'; |
7 | 13 | import type { Owner } from './proto/sui/rpc/v2/owner.js'; |
8 | 14 | import { Owner_OwnerKind } from './proto/sui/rpc/v2/owner.js'; |
@@ -46,6 +52,10 @@ import { |
46 | 52 | import { Value } from './proto/google/protobuf/struct.js'; |
47 | 53 | import { SimulateTransactionRequest_TransactionChecks } from './proto/sui/rpc/v2/transaction_execution_service.js'; |
48 | 54 |
|
| 55 | +// google.rpc.Code.NOT_FOUND — the only status we map to ObjectError('notFound'); |
| 56 | +// any other code collapses to 'unknown'. |
| 57 | +const GRPC_CODE_NOT_FOUND = 5; |
| 58 | + |
49 | 59 | export interface GrpcCoreClientOptions extends CoreClientOptions { |
50 | 60 | client: SuiGrpcClient; |
51 | 61 | } |
@@ -88,51 +98,59 @@ export class GrpcCoreClient extends CoreClient { |
88 | 98 | }); |
89 | 99 |
|
90 | 100 | results.push( |
91 | | - ...response.response.objects.map((object): SuiClientTypes.Object<Include> | Error => { |
92 | | - if (object.result.oneofKind === 'error') { |
93 | | - // TODO: improve error handling |
94 | | - return new Error(object.result.error.message); |
95 | | - } |
96 | | - |
97 | | - if (object.result.oneofKind !== 'object') { |
98 | | - return new Error('Unexpected result type'); |
99 | | - } |
100 | | - |
101 | | - const bcsContent = object.result.object.contents?.value ?? undefined; |
102 | | - const objectBcs = object.result.object.bcs?.value ?? undefined; |
103 | | - |
104 | | - // Package objects have type "package" which is not a struct tag, so don't normalize it |
105 | | - const objectType = object.result.object.objectType; |
106 | | - const type = |
107 | | - objectType && objectType.includes('::') |
108 | | - ? normalizeStructTag(objectType) |
109 | | - : (objectType ?? ''); |
110 | | - |
111 | | - const jsonContent = options.include?.json |
112 | | - ? object.result.object.json |
113 | | - ? (Value.toJson(object.result.object.json) as Record<string, unknown>) |
114 | | - : null |
115 | | - : undefined; |
116 | | - |
117 | | - const displayData = mapDisplayProto( |
118 | | - options.include?.display, |
119 | | - object.result.object.display, |
120 | | - ); |
121 | | - |
122 | | - return { |
123 | | - objectId: object.result.object.objectId!, |
124 | | - version: object.result.object.version?.toString()!, |
125 | | - digest: object.result.object.digest!, |
126 | | - content: bcsContent as SuiClientTypes.Object<Include>['content'], |
127 | | - owner: mapOwner(object.result.object.owner)!, |
128 | | - type, |
129 | | - previousTransaction: (object.result.object.previousTransaction ?? |
130 | | - undefined) as SuiClientTypes.Object<Include>['previousTransaction'], |
131 | | - objectBcs: objectBcs as SuiClientTypes.Object<Include>['objectBcs'], |
132 | | - json: jsonContent as SuiClientTypes.Object<Include>['json'], |
133 | | - display: displayData as SuiClientTypes.Object<Include>['display'], |
134 | | - }; |
135 | | - }), |
| 101 | + ...response.response.objects.map( |
| 102 | + (object, idx): SuiClientTypes.Object<Include> | ObjectError => { |
| 103 | + if (object.result.oneofKind === 'error') { |
| 104 | + const status = object.result.error; |
| 105 | + const code: ObjectErrorCode = |
| 106 | + status.code === GRPC_CODE_NOT_FOUND ? 'notFound' : 'unknown'; |
| 107 | + return new ObjectError(code, batch[idx], { |
| 108 | + transportDetails: { $kind: 'grpc', status }, |
| 109 | + }); |
| 110 | + } |
| 111 | + |
| 112 | + if (object.result.oneofKind !== 'object') { |
| 113 | + throw new SuiClientError( |
| 114 | + `Unexpected gRPC result kind: "${object.result.oneofKind}" — expected "object" or "error"`, |
| 115 | + ); |
| 116 | + } |
| 117 | + |
| 118 | + const bcsContent = object.result.object.contents?.value ?? undefined; |
| 119 | + const objectBcs = object.result.object.bcs?.value ?? undefined; |
| 120 | + |
| 121 | + // Package objects have type "package" which is not a struct tag, so don't normalize it |
| 122 | + const objectType = object.result.object.objectType; |
| 123 | + const type = |
| 124 | + objectType && objectType.includes('::') |
| 125 | + ? normalizeStructTag(objectType) |
| 126 | + : (objectType ?? ''); |
| 127 | + |
| 128 | + const jsonContent = options.include?.json |
| 129 | + ? object.result.object.json |
| 130 | + ? (Value.toJson(object.result.object.json) as Record<string, unknown>) |
| 131 | + : null |
| 132 | + : undefined; |
| 133 | + |
| 134 | + const displayData = mapDisplayProto( |
| 135 | + options.include?.display, |
| 136 | + object.result.object.display, |
| 137 | + ); |
| 138 | + |
| 139 | + return { |
| 140 | + objectId: object.result.object.objectId!, |
| 141 | + version: object.result.object.version?.toString()!, |
| 142 | + digest: object.result.object.digest!, |
| 143 | + content: bcsContent as SuiClientTypes.Object<Include>['content'], |
| 144 | + owner: mapOwner(object.result.object.owner)!, |
| 145 | + type, |
| 146 | + previousTransaction: (object.result.object.previousTransaction ?? |
| 147 | + undefined) as SuiClientTypes.Object<Include>['previousTransaction'], |
| 148 | + objectBcs: objectBcs as SuiClientTypes.Object<Include>['objectBcs'], |
| 149 | + json: jsonContent as SuiClientTypes.Object<Include>['json'], |
| 150 | + display: displayData as SuiClientTypes.Object<Include>['display'], |
| 151 | + }; |
| 152 | + }, |
| 153 | + ), |
136 | 154 | ); |
137 | 155 | } |
138 | 156 |
|
|
0 commit comments