Skip to content

Commit

Permalink
feat(Grpc-Web): Add & export GrpcWebError type (#593)
Browse files Browse the repository at this point in the history
* feat(Grpc-Web): Add & export GrpcWebError type

* refactor(GrpcWebError): Convert interface to a concrete error class

* refactor(GrpcWebError): Drop unneeded `Object.setPrototypeOf(this, GrpcWebError.prototype);` as ES5 is deprecated
  • Loading branch information
zak-cloudnc authored Aug 15, 2022
1 parent dbdced2 commit 645987d
Show file tree
Hide file tree
Showing 9 changed files with 70 additions and 19 deletions.
Binary file modified integration/avoid-import-conflicts/simple.bin
Binary file not shown.
Binary file modified integration/avoid-import-conflicts/simple2.bin
Binary file not shown.
9 changes: 8 additions & 1 deletion integration/grpc-web-no-streaming-observable/example.ts
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,8 @@ export class GrpcWebImpl {
debug: this.options.debug,
onEnd: (next) => {
if (next.status !== 0) {
observer.error({ code: next.status, message: next.statusMessage });
const err = new GrpcWebError(next.statusMessage, next.status, next.trailers);
observer.error(err);
} else {
observer.next(next.message as any);
observer.complete();
Expand Down Expand Up @@ -436,3 +437,9 @@ export type Exact<P, I extends P> = P extends Builtin
function isSet(value: any): boolean {
return value !== null && value !== undefined;
}

export class GrpcWebError extends Error {
constructor(message: string, public code: grpc.Code, public metadata: grpc.Metadata) {
super(message);
}
}
10 changes: 7 additions & 3 deletions integration/grpc-web-no-streaming/example.ts
Original file line number Diff line number Diff line change
Expand Up @@ -405,9 +405,7 @@ export class GrpcWebImpl {
if (response.status === grpc.Code.OK) {
resolve(response.message);
} else {
const err = new Error(response.statusMessage) as any;
err.code = response.status;
err.metadata = response.trailers;
const err = new GrpcWebError(response.statusMessage, response.status, response.trailers);
reject(err);
}
},
Expand Down Expand Up @@ -436,3 +434,9 @@ export type Exact<P, I extends P> = P extends Builtin
function isSet(value: any): boolean {
return value !== null && value !== undefined;
}

export class GrpcWebError extends Error {
constructor(message: string, public code: grpc.Code, public metadata: grpc.Metadata) {
super(message);
}
}
4 changes: 2 additions & 2 deletions integration/grpc-web/client-ts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ async function main() {
}

const obs = client.ActiveUserSettingsStream({});
await obs.forEach(value => {
console.log("Got", value);
await obs.forEach((value) => {
console.log('Got', value);
});
}

Expand Down
26 changes: 23 additions & 3 deletions integration/grpc-web/example-test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { DashStateClientImpl } from './example';
import { DashStateClientImpl, GrpcWebError, GrpcWebImpl } from './example';
import { EMPTY } from 'rxjs';
import { NodeHttpTransport } from '@improbable-eng/grpc-web-node-http-transport';

describe('grpc-web', () => {
it('at least compiles', () => {
Expand Down Expand Up @@ -27,7 +28,26 @@ describe('grpc-web', () => {
invoke: jest.fn(),
};
const client = new DashStateClientImpl(rpc);
const call = () => client.ChangeUserSettingsStream(EMPTY)
expect(call).toThrowError("ts-proto does not yet support client streaming!")
const call = () => client.ChangeUserSettingsStream(EMPTY);
expect(call).toThrowError('ts-proto does not yet support client streaming!');
});

it('throws error of type GrpcWebError', async () => {
const client = new DashStateClientImpl(
new GrpcWebImpl('', {
transport: NodeHttpTransport(),
})
);

try {
await client.UserSettings({});
} catch (e) {
expect(e).toBeInstanceOf(GrpcWebError);

if (e instanceof GrpcWebError) {
expect(e.code).toBeDefined();
expect(e.metadata).toBeDefined();
}
}
});
});
10 changes: 7 additions & 3 deletions integration/grpc-web/example.ts
Original file line number Diff line number Diff line change
Expand Up @@ -845,9 +845,7 @@ export class GrpcWebImpl {
if (response.status === grpc.Code.OK) {
resolve(response.message);
} else {
const err = new Error(response.statusMessage) as any;
err.code = response.status;
err.metadata = response.trailers;
const err = new GrpcWebError(response.statusMessage, response.status, response.trailers);
reject(err);
}
},
Expand Down Expand Up @@ -916,3 +914,9 @@ export type Exact<P, I extends P> = P extends Builtin
function isSet(value: any): boolean {
return value !== null && value !== undefined;
}

export class GrpcWebError extends Error {
constructor(message: string, public code: grpc.Code, public metadata: grpc.Metadata) {
super(message);
}
}
11 changes: 5 additions & 6 deletions src/generate-grpc-web.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ function generateGrpcWebImpl(ctx: Context, returnObservable: boolean, hasStreami
if (returnObservable) {
chunks.push(createObservableUnaryMethod(ctx));
} else {
chunks.push(createPromiseUnaryMethod());
chunks.push(createPromiseUnaryMethod(ctx));
}

if (hasStreamingMethods) {
Expand All @@ -225,7 +225,7 @@ function generateGrpcWebImpl(ctx: Context, returnObservable: boolean, hasStreami
return joinCode(chunks, { trim: false });
}

function createPromiseUnaryMethod(): Code {
function createPromiseUnaryMethod(ctx: Context): Code {
return code`
unary<T extends UnaryMethodDefinitionish>(
methodDesc: T,
Expand All @@ -248,9 +248,7 @@ function createPromiseUnaryMethod(): Code {
if (response.status === grpc.Code.OK) {
resolve(response.message);
} else {
const err = new Error(response.statusMessage) as any;
err.code = response.status;
err.metadata = response.trailers;
const err = new ${ctx.utils.GrpcWebError}(response.statusMessage, response.status, response.trailers);
reject(err);
}
},
Expand Down Expand Up @@ -281,7 +279,8 @@ function createObservableUnaryMethod(ctx: Context): Code {
debug: this.options.debug,
onEnd: (next) => {
if (next.status !== 0) {
observer.error({ code: next.status, message: next.statusMessage });
const err = new ${ctx.utils.GrpcWebError}(next.statusMessage, next.status, next.trailers);
observer.error(err);
} else {
observer.next(next.message as any);
observer.complete();
Expand Down
19 changes: 18 additions & 1 deletion src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,8 @@ export type Utils = ReturnType<typeof makeDeepPartial> &
ReturnType<typeof makeByteUtils> &
ReturnType<typeof makeLongUtils> &
ReturnType<typeof makeComparisonUtils> &
ReturnType<typeof makeNiceGrpcServerStreamingMethodResult>;
ReturnType<typeof makeNiceGrpcServerStreamingMethodResult> &
ReturnType<typeof makeGrpcWebErrorClass>;

/** These are runtime utility methods used by the generated code. */
export function makeUtils(options: Options): Utils {
Expand All @@ -330,6 +331,7 @@ export function makeUtils(options: Options): Utils {
...longs,
...makeComparisonUtils(),
...makeNiceGrpcServerStreamingMethodResult(),
...makeGrpcWebErrorClass(),
};
}

Expand Down Expand Up @@ -671,6 +673,21 @@ function makeNiceGrpcServerStreamingMethodResult() {
return { NiceGrpcServerStreamingMethodResult };
}

function makeGrpcWebErrorClass() {
const GrpcWebError = conditionalOutput(
'GrpcWebError',
code`
export class GrpcWebError extends Error {
constructor(message: string, public code: grpc.Code, public metadata: grpc.Metadata) {
super(message);
}
}
`
);

return { GrpcWebError };
}

// Create the interface with properties
function generateInterfaceDeclaration(
ctx: Context,
Expand Down

0 comments on commit 645987d

Please sign in to comment.