Skip to content

Commit a725341

Browse files
committed
print extra keys when stringifying
1 parent 2ba7e2d commit a725341

File tree

2 files changed

+78
-2
lines changed

2 files changed

+78
-2
lines changed

lib/client.ts

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,45 @@ function mapError(serviceName: string, methodName: string, errResult: any) {
110110
throw new RpcResponseError(source, errResult);
111111
}
112112

113-
class RpcResponseError {
113+
const EXCLUDED_META_KEYS = [
114+
"type",
115+
"code",
116+
"expose",
117+
"message",
118+
"namespace",
119+
"instance",
120+
"source",
121+
];
122+
123+
function logfmt(data: Record<string, any>) {
124+
// taken from https://github.com/csquared/node-logfmt/blob/master/lib/stringify.js
125+
var line = "";
126+
127+
for (var key in data) {
128+
if (EXCLUDED_META_KEYS.includes(key)) continue;
129+
130+
var value = data[key];
131+
var is_null = false;
132+
if (value == null) {
133+
is_null = true;
134+
value = "";
135+
} else value = value.toString();
136+
137+
var needs_quoting = value.indexOf(" ") > -1 || value.indexOf("=") > -1;
138+
var needs_escaping = value.indexOf('"') > -1 || value.indexOf("\\") > -1;
139+
140+
if (needs_escaping) value = value.replace(/["\\]/g, "\\$&");
141+
if (needs_quoting || needs_escaping) value = '"' + value + '"';
142+
if (value === "" && !is_null) value = '""';
143+
144+
line += key + "=" + value + " ";
145+
}
146+
147+
// trim trailing space
148+
return line.substring(0, line.length - 1);
149+
}
150+
151+
export class RpcResponseError {
114152
source?: string[];
115153

116154
constructor(source: string, responseBody: any) {
@@ -143,7 +181,9 @@ class RpcResponseError {
143181
toString() {
144182
// defineProperty not recognized by typescript, nor is the result of assign recognizable
145183
const { name, message, instance } = this as any;
146-
return `${name}: ${message} [${instance}]`;
184+
const meta = logfmt(this);
185+
186+
return `${name}: ${message} [${instance}]${meta ? " " + meta : ""}`;
147187
}
148188
}
149189

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)