1 | # node-grpc-error-details
|
2 |
|
3 | Utility function for deserializing the `grpc-status-details-bin` metadata value when using the [node grpc](https://github.com/grpc/grpc-node/tree/master/packages/grpc-native-core) package. Error details allow sending/receiving additional data along with an error. For instance, if a request sends invalid data, a gRPC server could send back a [BadRequest](./src/proto/error_details.proto#L119) message identifying the field and why it failed validation.
|
4 |
|
5 | gRPC services that send rich error details place information in the `grpc-status-details-bin` metadata property of the [ServiceError](https://grpc.io/grpc/node/grpc.html#~ServiceError) passed to the callback of a failed gRPC method call. The value of the `grpc-status-details-bin` field is a serialized [Status](./src/proto/status.proto) message. The Status message's details field is an array of [Any](https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/any.proto#L122) messages, which consist of a type field and the serialized data for that message type.
|
6 |
|
7 | This library, given an error, returns back the deserialized Status message and an array of deserialized detail messages.
|
8 |
|
9 | ## Install
|
10 |
|
11 | ```bash
|
12 | # yarn
|
13 | yarn add @stackpath/node-grpc-error-details
|
14 |
|
15 | # npm
|
16 | npm install @stackpath/node-grpc-error-details
|
17 | ```
|
18 |
|
19 | ## Usage
|
20 |
|
21 | Both exported functions return the same type of object.
|
22 |
|
23 | ```
|
24 | {
|
25 | status: Status
|
26 | details: DetailType[]
|
27 | }
|
28 | ```
|
29 |
|
30 | where `status` is a [Google rpc Status message](./src/proto/status.proto) and `details` is the `Status`'s details array with each item deserialized and unpacked from an `Any` message to its actual message type.
|
31 |
|
32 | `deserializeGrpcStatusDetails` allows passing in the `deserializeMap` argument, where each key is a message type and each value is its corresponding deserialize function.
|
33 |
|
34 | `deserializeGoogleGrpcStatusDetails` behaves exactly the same as `deserializeGrpcStatusDetails`, but provides a default deserializeMap using [Google's rpc error details types](./src/proto/error_details.proto).
|
35 |
|
36 | ### deserializeGrpcStatusDetails(error, deserializeMap)
|
37 |
|
38 | Example:
|
39 |
|
40 | ```js
|
41 | import { deserializeGrpcStatusDetails } from "@stackpath/node-grpc-error-details";
|
42 | import {
|
43 | RetryInfo,
|
44 | DebugInfo,
|
45 | QuotaFailure,
|
46 | PreconditionFailure,
|
47 | CustomError
|
48 | } from "./custom_error_pb";
|
49 |
|
50 | // Define the types of errors we want to deserialize
|
51 | const deserializeMap = {
|
52 | "stackpath.rpc.RetryInfo": RetryInfo.deserializeBinary,
|
53 | "stackpath.rpc.DebugInfo": DebugInfo.deserializeBinary,
|
54 | "stackpath.rpc.QuotaFailure": QuotaFailure.deserializeBinary,
|
55 | "stackpath.rpc.PreconditionFailure": PreconditionFailure.deserializeBinary,
|
56 | "stackpath.rpc.CustomError": CustomError.deserializeBinary
|
57 | };
|
58 |
|
59 | const point = { latitude: 409146138, longitude: -746188906 };
|
60 |
|
61 | // Make grpc call that fails and returns a Status object with
|
62 | // details in the `grpc-status-details-bin` Metadata property
|
63 | stub.getFeature(point, function(err, feature) {
|
64 | if (err) {
|
65 | const grpcErrorDetails = deserializeGrpcStatusDetails(err, deserializeMap);
|
66 | if (grpcErrorDetails) {
|
67 | const { status, details } = grpcErrorDetails;
|
68 |
|
69 | // Search for an instance of CustomError in details and do something if found
|
70 | for (let i = 0; i < details.length; i++) {
|
71 | if (details[i] instanceof CustomError) {
|
72 | console.log(details[i].toObject());
|
73 | }
|
74 | }
|
75 | }
|
76 | } else {
|
77 | // process feature
|
78 | }
|
79 | });
|
80 | ```
|
81 |
|
82 | ### deserializeGoogleGrpcStatusDetails(error)
|
83 |
|
84 | Example:
|
85 |
|
86 | ```js
|
87 | import {
|
88 | deserializeGoogleGrpcStatusDetails,
|
89 | BadRequest
|
90 | } from "@stackpath/node-grpc-error-details";
|
91 |
|
92 | const point = { latitude: 409146138, longitude: -746188906 };
|
93 |
|
94 | // Make grpc call that fails and returns a Status object with
|
95 | // details in the `grpc-status-details-bin` Metadata property
|
96 | stub.getFeature(point, function(err, feature) {
|
97 | if (err) {
|
98 | const grpcErrorDetails = deserializeGoogleGrpcStatusDetails(err);
|
99 | if (grpcErrorDetails) {
|
100 | const { status, details } = grpcErrorDetails;
|
101 |
|
102 | // Search for an instance of BadRequest in details and do something if found
|
103 | for (let i = 0; i < details.length; i++) {
|
104 | if (details[i] instanceof BadRequest) {
|
105 | console.log(details[i].toObject());
|
106 | }
|
107 | }
|
108 | }
|
109 | } else {
|
110 | // process feature
|
111 | }
|
112 | });
|
113 | ```
|