Skip to content

Commit 2422594

Browse files
authored
refactor: better logging and catch all possible errors (#4)
1 parent 3adc26b commit 2422594

File tree

3 files changed

+139
-32
lines changed

3 files changed

+139
-32
lines changed

package-lock.json

Lines changed: 84 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
"dependencies": {
1010
"@fastify/http-proxy": "^11.1.2",
1111
"apify": "^3.2.6",
12-
"fastify": "^5.3.3"
12+
"fastify": "^5.3.3",
13+
"pino-pretty": "^13.0.0"
1314
},
1415
"devDependencies": {
1516
"@apify/eslint-config": "^1.0.0",

src/main.ts

Lines changed: 53 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { text } from 'node:stream/consumers';
44
import FastifyProxy from '@fastify/http-proxy';
55
import { Actor } from 'apify';
66
import Fastify from 'fastify';
7+
import type PinoPretty from 'pino-pretty';
78

89
await Actor.init();
910

@@ -17,7 +18,17 @@ if (!OPENROUTER_API_KEY) {
1718
}
1819

1920
const server = Fastify({
20-
logger: true,
21+
logger: {
22+
transport: {
23+
target: 'pino-pretty',
24+
options: {
25+
colorize: true,
26+
minimumLevel: 'debug',
27+
ignore: 'hostname,time,pid,reqId',
28+
messageFormat: '{if reqId}[{reqId}] {end}{msg}',
29+
} as PinoPretty.PrettyOptions,
30+
},
31+
},
2132
});
2233

2334
server.get('/', async (request, reply) => {
@@ -53,7 +64,8 @@ server.register(FastifyProxy, {
5364
},
5465
proxyPayloads: false, // Disable proxy payload, request body will be decoded and modified by preHandler
5566
replyOptions: {
56-
onResponse: (request, reply, res) => {
67+
// eslint-disable-next-line @typescript-eslint/no-misused-promises
68+
onResponse: async (request, reply, res) => {
5769
// @ts-expect-error stream is not defined in the type definitions
5870
const stream = res.stream as NodeJS.ReadableStream;
5971

@@ -63,36 +75,49 @@ server.register(FastifyProxy, {
6375
// Direct stream to the reply, don't wait for JSON parse
6476
reply.send(stream);
6577

66-
// Wait for end of stream and read as text
67-
text(streamClone)
68-
.then((response) => {
69-
const isStream = response.startsWith('data:') || response.startsWith(': OPENROUTER PROCESSING');
70-
71-
if (isStream) {
72-
request.log.info('Stream response mode');
73-
const lines = response.split('\n').filter((line) => line.trim());
74-
const data = JSON.parse(lines[lines.length - 2].replace('data: ', ''));
75-
return data.usage?.cost || 0;
76-
}
77-
78-
request.log.info('Single response mode');
79-
const json = JSON.parse(response);
80-
request.log.info(`Cost ${json.usage.cost}`);
81-
return json.usage?.cost || 0;
82-
})
83-
.then(chargeUser)
84-
.catch(console.error);
78+
let response;
79+
try {
80+
// Wait for end of stream and read as text
81+
response = await text(streamClone);
82+
} catch (error) {
83+
request.log.error({ error }, 'Cannot read response');
84+
return;
85+
}
86+
87+
let jsonString;
88+
const isStream = response.startsWith('data:') || response.startsWith(': OPENROUTER PROCESSING');
89+
if (isStream) {
90+
request.log.info('Stream response mode');
91+
const lines = response.split('\n').filter((line) => line.trim());
92+
jsonString = lines[lines.length - 2].replace('data: ', '');
93+
} else {
94+
jsonString = response;
95+
}
96+
97+
let data;
98+
try {
99+
data = JSON.parse(jsonString);
100+
} catch (error) {
101+
request.log.error({ error, jsonString }, 'Failed to parse JSON response');
102+
return;
103+
}
104+
105+
// eslint-disable-next-line prefer-destructuring
106+
const cost = data.usage.cost;
107+
if (!cost) {
108+
request.log.error({ data }, 'Cannot read cost from response');
109+
return;
110+
}
111+
112+
const costWithFee = cost * 1.1; // Add 10% fee
113+
const count = Math.max(Math.round(costWithFee / 0.0001), 1);
114+
request.log.info({ originalCost: cost, costWithFee }, `Charging $0.0001 x ${count} times`);
115+
116+
await Actor.charge({ eventName: 'credit-0-0001', count });
85117
},
86118
},
87119
});
88120

89-
async function chargeUser(amount: number) {
90-
const chargePrice = amount * 1.1; // Add 10% fee
91-
const count = Math.max(Math.round(chargePrice / 0.0001), 1);
92-
console.log(`Charging $${chargePrice}, by charge $0.0001 x ${count} times`);
93-
await Actor.charge({ eventName: 'credit-0-0001', count });
94-
}
95-
96121
process.on('SIGTERM', async () => {
97122
console.log('Received SIGTERM, shutting down gracefully');
98123
await server.close();

0 commit comments

Comments
 (0)