Skip to content

Commit f6dc193

Browse files
committed
log error - show tags and meta
1 parent 7721a54 commit f6dc193

File tree

8 files changed

+174
-48
lines changed

8 files changed

+174
-48
lines changed

.vscode/settings.json

Lines changed: 0 additions & 5 deletions
This file was deleted.

index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* limitations under the License.
1616
*/
1717

18-
const { unique, only } = require('./src/filter');
18+
const { unique, only } = require('./dist/misc');
1919

2020
module.exports = Object.assign({}, {
2121
node: require('./src/node'),
@@ -25,7 +25,7 @@ module.exports = Object.assign({}, {
2525
traverse: require('./src/traverse'),
2626
template: require('./src/template'),
2727
log: require('./src/log'),
28-
api: require('./src/api'),
28+
api: require('./dist/api'),
2929
unique,
3030
only
3131
});

lib/api.ts

Lines changed: 95 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
//import { resolve, parse } from "url";
2-
//import { join } from "path";
3-
4-
import { unique } from './misc.ts';
1+
import { unique } from './misc';
2+
import statusCodes from './codes';
53

64
export type ItemId = string;
75

@@ -27,6 +25,15 @@ export type ApiErrorHelper = {
2725
links?: string[];
2826
};
2927

28+
export type KVM = { [k: string]: string };
29+
30+
export type RequestOptions<T = unknown> = {
31+
url: string;
32+
method?: 'GET' | 'POST' | 'PATCH' | 'DELETE';
33+
headers?: KVM;
34+
body?: T;
35+
};
36+
3037
export class ApiError extends Error {
3138
jti: string = '';
3239
url: string = '';
@@ -75,6 +82,13 @@ export class ApiError extends Error {
7582
this.url = url;
7683
return this;
7784
}
85+
86+
static fromJson(opts: RequestOptions, json: ApiError, statusCode = 500) {
87+
return new ApiError(json.message)
88+
.withCode(statusCode)
89+
.withTags(json.tags)
90+
.withUrl(opts.url);
91+
}
7892
}
7993

8094
export class NginxError extends ApiError {
@@ -85,42 +99,87 @@ export class NginxError extends ApiError {
8599
return this;
86100
}
87101

88-
static fromHtml(resp = '', statusCode = 500) {
102+
static fromHtml(opts: RequestOptions, resp = '', statusCode = 500) {
89103
let [, title = 'Unknown nginx errror'] = /<title>(.*?)<\/title>/gi.exec(resp) || [];
90104
title = title.replace(statusCode.toString(), '').trim();
91105

92-
// return new NginxError(http.STATUS_CODES[statusCode])
93-
// .withCode(statusCode)
94-
// .withTitle(title);
106+
return new NginxError(statusCodes[statusCode])
107+
.withCode(statusCode)
108+
.withTitle(title)
109+
.withUrl(opts.url);
95110
}
96111
}
97112

98-
type KVM = { [k: string]: string };
113+
export function nodeReq<Q = unknown, S = unknown>(opts: RequestOptions<Q>): Promise<S> {
114+
const { protocol, hostname, port, pathname } = new URL(opts.url);
99115

100-
export interface RequestOptions {
101-
method?: 'GET' | 'POST' | 'PATCH' | 'DELETE';
102-
headers?: KVM;
103-
}
116+
const proto = protocol === 'https:' ? require('https') : require('http');
104117

105-
export async function req<T, U = unknown>(
106-
url: string,
107-
opts: RequestOptions = {},
108-
data?: U
109-
) {
110-
const resp = await fetch(url, {
118+
const options = {
119+
method: 'GET',
120+
host: hostname,
121+
port: +port,
122+
path: pathname,
111123
...opts
124+
};
125+
126+
if (!port) {
127+
options.port = protocol === 'https:' ? 443 : 80;
128+
}
129+
130+
return new Promise((resolve, reject) => {
131+
const req = proto.request(options, (res) => {
132+
let resp = '';
133+
res.on('data', (chunk) => (resp += chunk.toString()));
134+
res.on('end', () => {
135+
try {
136+
/*
137+
* most nginx upstream errors should be handled by ingress default-backend
138+
* but who knows ...
139+
*/
140+
if (resp.startsWith('<html>') && resp.includes('nginx')) {
141+
return reject(NginxError.fromHtml(opts, resp, res.statusCode));
142+
}
143+
const json = JSON.parse(resp);
144+
if (res.statusCode >= 400) {
145+
return reject(ApiError.fromJson(opts, json, res.statusCode));
146+
}
147+
resolve(json);
148+
} catch (err) {
149+
console.log(resp);
150+
reject(err);
151+
}
152+
});
153+
});
154+
155+
req.on('error', (err) => reject(err));
156+
157+
if (opts.body) {
158+
let send = opts.body as any;
159+
if (typeof send === 'object') {
160+
send = JSON.stringify(opts.body);
161+
}
162+
req.write(send);
163+
}
164+
req.end();
112165
});
166+
}
113167

114-
const json = await resp.json();
168+
export async function req<Q = unknown, S = unknown>(opts: RequestOptions<Q>): Promise<S> {
169+
if (typeof fetch !== 'function') {
170+
return nodeReq(opts);
171+
}
115172

116-
console.log('.xxx', resp.status);
173+
const resp = await fetch(opts.url, {
174+
headers: opts.headers,
175+
method: opts.method || 'GET',
176+
body: <any>opts.body || null
177+
});
117178

118-
if (resp.status >= 300) {
119-
throw new ApiError(json.message)
120-
.withHelper(json.helper)
121-
.withTags(json.tags)
122-
.withCode(resp.status)
123-
.withUrl(url);
179+
const json = await resp.json();
180+
181+
if (resp.status >= 400) {
182+
throw ApiError.fromJson(opts, json, resp.status);
124183
}
125184

126185
return json;
@@ -158,28 +217,33 @@ export class Client {
158217
get<T = unknown>(path: string, query = {}): Promise<T> {
159218
const url = new URL(path, this.url);
160219
const headers = this.getDefaultHeaders();
161-
return req(url.toString(), { method: 'GET', headers });
220+
return req({ url: url.toString(), method: 'GET', headers });
162221
}
163222

164223
post<T = unknown>(path: string, data: Partial<T> = {}): Promise<T> {
165224
const url = new URL(path, this.url);
166225
const headers = this.getDefaultHeaders();
167-
return req(url.toString(), { method: 'POST', headers }, data);
226+
return req({ url: url.toString(), method: 'POST', headers, body: data });
168227
}
169228

170229
patch<T = unknown>(path: string, data: Partial<T> = {}): Promise<T> {
171230
const url = new URL(path, this.url);
172231
const headers = this.getDefaultHeaders();
173-
return req(url.toString(), { method: 'PATCH', headers }, data);
232+
return req({ url: url.toString(), method: 'PATCH', headers, body: data });
174233
}
175234

176235
delete<T = unknown>(path: string): Promise<T> {
177236
const url = new URL(path, this.url);
178237
const headers = this.getDefaultHeaders();
179-
return req(url.toString(), { method: 'DELETE', headers });
238+
return req({ url: url.toString(), method: 'DELETE', headers });
180239
}
181240

182241
with(opts: ClientOpts = {}) {
183242
return new Client({ ...(this._opts || {}), ...opts });
184243
}
185244
}
245+
246+
export default new Client({
247+
url: process.env['RIC_URL'] || 'https://dev.rightech.io/',
248+
token: process.env['RIC_TOKEN']
249+
});

lib/codes.ts

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
export default {
2+
'100': 'Continue',
3+
'101': 'Switching Protocols',
4+
'102': 'Processing',
5+
'103': 'Early Hints',
6+
'200': 'OK',
7+
'201': 'Created',
8+
'202': 'Accepted',
9+
'203': 'Non-Authoritative Information',
10+
'204': 'No Content',
11+
'205': 'Reset Content',
12+
'206': 'Partial Content',
13+
'207': 'Multi-Status',
14+
'208': 'Already Reported',
15+
'226': 'IM Used',
16+
'300': 'Multiple Choices',
17+
'301': 'Moved Permanently',
18+
'302': 'Found',
19+
'303': 'See Other',
20+
'304': 'Not Modified',
21+
'305': 'Use Proxy',
22+
'307': 'Temporary Redirect',
23+
'308': 'Permanent Redirect',
24+
'400': 'Bad Request',
25+
'401': 'Unauthorized',
26+
'402': 'Payment Required',
27+
'403': 'Forbidden',
28+
'404': 'Not Found',
29+
'405': 'Method Not Allowed',
30+
'406': 'Not Acceptable',
31+
'407': 'Proxy Authentication Required',
32+
'408': 'Request Timeout',
33+
'409': 'Conflict',
34+
'410': 'Gone',
35+
'411': 'Length Required',
36+
'412': 'Precondition Failed',
37+
'413': 'Payload Too Large',
38+
'414': 'URI Too Long',
39+
'415': 'Unsupported Media Type',
40+
'416': 'Range Not Satisfiable',
41+
'417': 'Expectation Failed',
42+
'418': "I'm a Teapot",
43+
'421': 'Misdirected Request',
44+
'422': 'Unprocessable Entity',
45+
'423': 'Locked',
46+
'424': 'Failed Dependency',
47+
'425': 'Unordered Collection',
48+
'426': 'Upgrade Required',
49+
'428': 'Precondition Required',
50+
'429': 'Too Many Requests',
51+
'431': 'Request Header Fields Too Large',
52+
'451': 'Unavailable For Legal Reasons',
53+
'500': 'Internal Server Error',
54+
'501': 'Not Implemented',
55+
'502': 'Bad Gateway',
56+
'503': 'Service Unavailable',
57+
'504': 'Gateway Timeout',
58+
'505': 'HTTP Version Not Supported',
59+
'506': 'Variant Also Negotiates',
60+
'507': 'Insufficient Storage',
61+
'508': 'Loop Detected',
62+
'509': 'Bandwidth Limit Exceeded',
63+
'510': 'Not Extended',
64+
'511': 'Network Authentication Required'
65+
};

lib/index.ts

Lines changed: 0 additions & 8 deletions
This file was deleted.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@rightech/utils",
3-
"version": "1.1.16",
3+
"version": "1.1.17",
44
"description": "",
55
"main": "index.js",
66
"private": false,
@@ -29,6 +29,7 @@
2929
"typings": "index.d.ts",
3030
"devDependencies": {
3131
"ts-loader": "^8.0.17",
32+
"typescript": "^4.2.3",
3233
"webpack": "^5.24.2",
3334
"webpack-cli": "^4.5.0"
3435
}

src/log.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,15 @@ function summary(message) {
7575
}
7676
if (message instanceof Error) {
7777
const joiner = colors.red('* ');
78-
return message.stack.split(' at').join(joiner);
78+
let [msg, ...rest] = message.stack.split(' at');
79+
msg = msg.trim();
80+
if (message.tags && message.tags.length) {
81+
msg = `${msg} ${JSON.stringify(message.tags)}`
82+
}
83+
if (message.more) {
84+
msg = `${msg} with ${JSON.stringify(message.more)}`
85+
}
86+
return [`${msg}\n `, ...rest].join(joiner);
7987
}
8088
return inspect(message);
8189
}

tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"resolveJsonModule": true,
88
"moduleResolution": "node",
99
"target": "ES2020",
10+
"module": "commonjs",
1011
"lib": ["es5", "es2020", "dom"],
1112
"allowJs": true,
1213
"baseUrl": "."

0 commit comments

Comments
 (0)