|
1 | 1 | import { Metadata, StatusObject } from '@grpc/grpc-js';
|
| 2 | +import { Status } from './cli-protocol/google/rpc/status_pb'; |
| 3 | +import { stringToUint8Array } from '../common/utils'; |
| 4 | +import { ProgrammerIsRequiredForUploadError } from './cli-protocol/cc/arduino/cli/commands/v1/upload_pb'; |
| 5 | + |
| 6 | +type ProtoError = typeof ProgrammerIsRequiredForUploadError; |
| 7 | +const protoErrorsMap = new Map<string, ProtoError>([ |
| 8 | + [ |
| 9 | + 'type.googleapis.com/cc.arduino.cli.commands.v1.ProgrammerIsRequiredForUploadError', |
| 10 | + ProgrammerIsRequiredForUploadError, |
| 11 | + ], |
| 12 | + // handle other cli defined errors here |
| 13 | +]); |
2 | 14 |
|
3 | 15 | export type ServiceError = StatusObject & Error;
|
4 | 16 | export namespace ServiceError {
|
5 | 17 | export function isCancel(arg: unknown): arg is ServiceError & { code: 1 } {
|
6 | 18 | return is(arg) && arg.code === 1; // https://grpc.github.io/grpc/core/md_doc_statuscodes.html
|
7 | 19 | }
|
| 20 | + |
8 | 21 | export function is(arg: unknown): arg is ServiceError {
|
9 |
| - return arg instanceof Error && isStatusObjet(arg); |
| 22 | + return arg instanceof Error && isStatusObject(arg); |
10 | 23 | }
|
11 |
| - function isStatusObjet(arg: unknown): arg is StatusObject { |
| 24 | + |
| 25 | + export function isInstanceOf(arg: unknown, type: unknown): boolean { |
| 26 | + if (!isStatusObject(arg)) { |
| 27 | + return false; |
| 28 | + } |
| 29 | + |
| 30 | + const bin = arg.metadata.get('grpc-status-details-bin')[0]; |
| 31 | + |
| 32 | + const uint8Array = |
| 33 | + typeof bin === 'string' |
| 34 | + ? stringToUint8Array(bin) |
| 35 | + : new Uint8Array(bin.buffer, bin.byteOffset, bin.byteLength); |
| 36 | + |
| 37 | + const errors = Status.deserializeBinary(uint8Array) |
| 38 | + .getDetailsList() |
| 39 | + .map((details) => { |
| 40 | + const typeUrl = details.getTypeUrl(); |
| 41 | + const ErrorType = protoErrorsMap.get(typeUrl); |
| 42 | + return ErrorType?.deserializeBinary(details.getValue_asU8()); |
| 43 | + }); |
| 44 | + |
| 45 | + return !!errors.find((error) => { |
| 46 | + // eslint-disable-next-line @typescript-eslint/no-explicit-any |
| 47 | + return error && error instanceof <any>type; |
| 48 | + }); |
| 49 | + } |
| 50 | + |
| 51 | + function isStatusObject(arg: unknown): arg is StatusObject { |
12 | 52 | if (typeof arg === 'object') {
|
13 | 53 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
14 | 54 | const any = arg as any;
|
|
0 commit comments