Skip to content

Commit ebb5334

Browse files
authored
Merge pull request #27 from LOKE/feature/fix-error-tostring
Fix: error.toString shows [object Object]
2 parents d5f4d35 + ac32bf8 commit ebb5334

File tree

2 files changed

+67
-2
lines changed

2 files changed

+67
-2
lines changed

lib/client.ts

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { format } from "util";
12
import fetch from "node-fetch";
23
import * as context from "@loke/context";
34

@@ -110,7 +111,26 @@ function mapError(serviceName: string, methodName: string, errResult: any) {
110111
throw new RpcResponseError(source, errResult);
111112
}
112113

113-
class RpcResponseError {
114+
const EXCLUDED_META_KEYS = [
115+
"type",
116+
"code",
117+
"expose",
118+
"message",
119+
"namespace",
120+
"instance",
121+
"source",
122+
];
123+
124+
function metaToString(meta: Record<string, any>) {
125+
if (!meta) return "";
126+
127+
return Object.keys(meta)
128+
.filter((k) => !EXCLUDED_META_KEYS.includes(k))
129+
.map((k) => format("%s=%j", k, meta[k]))
130+
.join(" ");
131+
}
132+
133+
export class RpcResponseError {
114134
source?: string[];
115135

116136
constructor(source: string, responseBody: any) {
@@ -121,8 +141,9 @@ class RpcResponseError {
121141
writable: true,
122142
});
123143

144+
// .message .code .type .expose .instance .type are applied here
124145
Object.assign(this, responseBody);
125-
if (!this.source) this.source = [];
146+
126147
this.source = [source, ...(this.source || [])];
127148

128149
Object.defineProperty(this, "stack", {
@@ -138,6 +159,14 @@ class RpcResponseError {
138159
writable: true,
139160
});
140161
}
162+
163+
toString() {
164+
// defineProperty not recognized by typescript, nor is the result of assign recognizable
165+
const { name, message, instance } = this as any;
166+
const meta = metaToString(this);
167+
168+
return `${name}: ${message} [${instance}]${meta ? " " + meta : ""}`;
169+
}
141170
}
142171

143172
export class RPCClient extends BaseClient {

test/rpc-response-error.test.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import test from "ava";
2+
3+
import { RpcResponseError } from "../lib/client";
4+
5+
test("RpcResponseError", (t) => {
6+
const err: any = new RpcResponseError("my_source", {
7+
type: "FooError",
8+
code: 123,
9+
expose: true,
10+
message: "foo",
11+
namespace: "foo",
12+
instance: "bar",
13+
source: ["foo", "bar"],
14+
upstreamCode: 456,
15+
upstreamMessage: "a bad thing happened",
16+
});
17+
18+
t.is(
19+
err.toString(),
20+
'RpcResponseError: foo [bar] upstreamCode=456 upstreamMessage="a bad thing happened"'
21+
);
22+
t.is(err.name, "RpcResponseError");
23+
t.is(err.type, "FooError");
24+
t.is(err.code, 123);
25+
t.is(err.expose, true);
26+
t.is(err.message, "foo");
27+
t.is(err.namespace, "foo");
28+
t.is(err.instance, "bar");
29+
t.deepEqual(err.source, ["my_source", "foo", "bar"]);
30+
t.is(
31+
err.stack,
32+
'RpcResponseError: foo [bar] upstreamCode=456 upstreamMessage="a bad thing happened"\n via bar\n via foo\n via my_source'
33+
);
34+
t.is(err.upstreamCode, 456);
35+
t.is(err.upstreamMessage, "a bad thing happened");
36+
});

0 commit comments

Comments
 (0)