@quatrain/worker 1.2.10 → 1.2.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/FileSystem.js +19 -56
- package/dist/FileSystem.test.js +8 -2
- package/dist/Helpers.d.ts +2 -1
- package/dist/Helpers.js +7 -1
- package/dist/Worker.d.ts +2 -2
- package/dist/Worker.js +8 -9
- package/dist/Worker.test.js +6 -9
- package/package.json +1 -1
- package/src/FileSystem.test.ts +9 -2
- package/src/FileSystem.ts +19 -65
- package/src/Helpers.ts +8 -1
- package/src/Worker.test.ts +6 -10
- package/src/Worker.ts +9 -10
package/dist/FileSystem.js
CHANGED
|
@@ -37,7 +37,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
exports.FileSystem = void 0;
|
|
40
|
-
const node_fs_1 =
|
|
40
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
41
41
|
const node_path_1 = __importDefault(require("node:path"));
|
|
42
42
|
const axios_1 = __importDefault(require("axios"));
|
|
43
43
|
const Worker_1 = require("./Worker");
|
|
@@ -141,63 +141,26 @@ class FileSystem {
|
|
|
141
141
|
meta = { ...meta, ...info };
|
|
142
142
|
Worker_1.Worker.info(`Uploading file ${filename} to ${meta.uploadUrl}`);
|
|
143
143
|
const { size } = node_fs_1.default.statSync(filename);
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
'Content-length': String(size),
|
|
154
|
-
},
|
|
155
|
-
})
|
|
156
|
-
.then(() => resolve({ ...meta, size, uploadUrl: undefined }))
|
|
157
|
-
.catch((err) => {
|
|
158
|
-
Worker_1.Worker.error(`An error occured while uploading ${filename}: ${err.message}`);
|
|
159
|
-
reject(err);
|
|
160
|
-
});
|
|
144
|
+
try {
|
|
145
|
+
Worker_1.Worker.info(`Uploading file ${filename} with size ${size} bytes`);
|
|
146
|
+
const fileBuffer = node_fs_1.default.readFileSync(filename);
|
|
147
|
+
const res = await (0, node_fetch_native_1.default)(meta.uploadUrl, {
|
|
148
|
+
method: 'PUT',
|
|
149
|
+
body: fileBuffer,
|
|
150
|
+
headers: {
|
|
151
|
+
'Content-Type': meta.contentType || mime,
|
|
152
|
+
},
|
|
161
153
|
});
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
let done = 0; // total bytes uploaded
|
|
166
|
-
let prev = 0; // latest value of done stored when % done was displayed
|
|
167
|
-
const { size } = node_fs_1.default.statSync(filename);
|
|
168
|
-
const readStream = node_fs_1.default.createReadStream(filename);
|
|
169
|
-
const sizeMB = (size / (1024 * 1024)).toFixed(2);
|
|
170
|
-
readStream.on('data', (data) => {
|
|
171
|
-
done += data.length;
|
|
172
|
-
if (done - prev >= size / 20) {
|
|
173
|
-
// only display message when 5% more has been uploaded
|
|
174
|
-
Worker_1.Worker.info(`${((done / size) * 100).toFixed(2)}% - ${(done /
|
|
175
|
-
(1024 * 1024)).toFixed(2)}MB / ${sizeMB}MB`);
|
|
176
|
-
prev = done;
|
|
177
|
-
}
|
|
178
|
-
});
|
|
179
|
-
Worker_1.Worker.info(`Uploading file ${filename} with size ${size} bytes`);
|
|
180
|
-
(0, node_fetch_native_1.default)(meta.uploadUrl, {
|
|
181
|
-
method: 'PUT',
|
|
182
|
-
mode: 'cors',
|
|
183
|
-
duplex: 'half',
|
|
184
|
-
body: readStream,
|
|
185
|
-
headers: {
|
|
186
|
-
'Content-Type': meta.contentType || mime,
|
|
187
|
-
'Content-length': String(size),
|
|
188
|
-
},
|
|
189
|
-
})
|
|
190
|
-
.then(() => resolve({ ...meta, size, uploadUrl: undefined }))
|
|
191
|
-
.catch((err) => {
|
|
192
|
-
Worker_1.Worker.error(`An error occured while uploading ${filename}: ${err.message}`);
|
|
193
|
-
reject(err);
|
|
194
|
-
});
|
|
154
|
+
if (res && res.ok === false) {
|
|
155
|
+
const errorText = typeof res.text === 'function' ? await res.text().catch(() => '') : '';
|
|
156
|
+
throw new Error(`HTTP upload failed with status ${res.status || 'unknown'}: ${errorText}`);
|
|
195
157
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
}
|
|
200
|
-
|
|
158
|
+
return { ...meta, size, uploadUrl: undefined };
|
|
159
|
+
}
|
|
160
|
+
catch (err) {
|
|
161
|
+
Worker_1.Worker.error(`An error occured while uploading ${filename}: ${err.message}`);
|
|
162
|
+
throw err;
|
|
163
|
+
}
|
|
201
164
|
}
|
|
202
165
|
/**
|
|
203
166
|
* Return meta data on given file
|
package/dist/FileSystem.test.js
CHANGED
|
@@ -94,6 +94,12 @@ describe('FileSystem Utilities (Worker)', () => {
|
|
|
94
94
|
jest.spyOn(node_fs_1.default, 'createReadStream').mockImplementation(() => {
|
|
95
95
|
return node_stream_1.Readable.from(Buffer.alloc(35 * 1024));
|
|
96
96
|
});
|
|
97
|
+
jest.spyOn(node_fs_1.default, 'readFileSync').mockImplementation((p) => {
|
|
98
|
+
if (typeof p === 'string' && (p.endsWith('test.txt') || p.endsWith('small.mp4') || p.endsWith('large.mp4') || p.endsWith('large-fail.mp4') || p.endsWith('small-fail.mp4') || p.endsWith('large-sync-fail.mp4'))) {
|
|
99
|
+
return Buffer.alloc(35 * 1024);
|
|
100
|
+
}
|
|
101
|
+
return (jest.requireActual('node:fs').readFileSync)(p);
|
|
102
|
+
});
|
|
97
103
|
jest.spyOn(node_fs_1.default, 'existsSync').mockImplementation((p) => {
|
|
98
104
|
if (typeof p === 'string' && (p.endsWith('test.txt') || p.endsWith('small.mp4') || p.endsWith('large.mp4') || p.endsWith('large-fail.mp4') || p.endsWith('small-fail.mp4') || p.endsWith('large-sync-fail.mp4'))) {
|
|
99
105
|
return true;
|
|
@@ -330,8 +336,8 @@ describe('FileSystem Utilities (Worker)', () => {
|
|
|
330
336
|
ffmpeg.ffprobe.mockImplementation((file, callback) => {
|
|
331
337
|
callback(null, mockMetadata);
|
|
332
338
|
});
|
|
333
|
-
// Make
|
|
334
|
-
jest.spyOn(node_fs_1.default, '
|
|
339
|
+
// Make readFileSync throw a synchronous error
|
|
340
|
+
jest.spyOn(node_fs_1.default, 'readFileSync').mockImplementationOnce(() => {
|
|
335
341
|
throw new Error('Sync stream error');
|
|
336
342
|
});
|
|
337
343
|
const meta = {
|
package/dist/Helpers.d.ts
CHANGED
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
* General utility class providing common static helpers for workers.
|
|
3
3
|
*/
|
|
4
4
|
export declare class Helpers {
|
|
5
|
+
private static _ffmpegPathPromise;
|
|
5
6
|
/** Default absolute path to the system's FFmpeg binary. */
|
|
6
|
-
static FFMPEG: Promise<string>;
|
|
7
|
+
static get FFMPEG(): Promise<string>;
|
|
7
8
|
/**
|
|
8
9
|
* Generate a thubnail from a video file at given frame position
|
|
9
10
|
* @param videoPath path to video file
|
package/dist/Helpers.js
CHANGED
|
@@ -6,8 +6,14 @@ const Worker_1 = require("./Worker");
|
|
|
6
6
|
* General utility class providing common static helpers for workers.
|
|
7
7
|
*/
|
|
8
8
|
class Helpers {
|
|
9
|
+
static _ffmpegPathPromise = null;
|
|
9
10
|
/** Default absolute path to the system's FFmpeg binary. */
|
|
10
|
-
static FFMPEG
|
|
11
|
+
static get FFMPEG() {
|
|
12
|
+
if (!this._ffmpegPathPromise) {
|
|
13
|
+
this._ffmpegPathPromise = Worker_1.Worker.getSystemCommandPath('ffmpeg').catch(() => 'ffmpeg');
|
|
14
|
+
}
|
|
15
|
+
return this._ffmpegPathPromise;
|
|
16
|
+
}
|
|
11
17
|
/**
|
|
12
18
|
* Generate a thubnail from a video file at given frame position
|
|
13
19
|
* @param videoPath path to video file
|
package/dist/Worker.d.ts
CHANGED
|
@@ -25,7 +25,7 @@ export declare class Worker extends Core {
|
|
|
25
25
|
* @param ts timestamp
|
|
26
26
|
* @returns boolean
|
|
27
27
|
*/
|
|
28
|
-
static pushEvent(event: string, data?: {}, ts?: number):
|
|
28
|
+
static pushEvent(event: string, data?: {}, ts?: number): void;
|
|
29
29
|
/**
|
|
30
30
|
* Async Push an event to the backend endpoint, if available
|
|
31
31
|
* @param event string
|
|
@@ -33,7 +33,7 @@ export declare class Worker extends Core {
|
|
|
33
33
|
* @param ts timestamp
|
|
34
34
|
* @returns boolean
|
|
35
35
|
*/
|
|
36
|
-
static pushEventAsync(event: string, data?: {}, ts?: number): Promise<
|
|
36
|
+
static pushEventAsync(event: string, data?: {}, ts?: number): Promise<true | undefined>;
|
|
37
37
|
/**
|
|
38
38
|
* Global handling function to process received messages
|
|
39
39
|
* @param messageHandler function
|
package/dist/Worker.js
CHANGED
|
@@ -59,8 +59,8 @@ class Worker extends core_1.Core {
|
|
|
59
59
|
*/
|
|
60
60
|
static pushEvent(event, data = {}, ts = 0) {
|
|
61
61
|
if (!this.endpoint) {
|
|
62
|
-
Worker.
|
|
63
|
-
|
|
62
|
+
Worker.error(`Events endpoint is mandatory but missing! Cannot report job status to source.`);
|
|
63
|
+
throw new Error(`Events endpoint is mandatory but missing`);
|
|
64
64
|
}
|
|
65
65
|
ts = ts === Date.now() ? Date.now() + 1 : Date.now();
|
|
66
66
|
const payload = {
|
|
@@ -79,8 +79,7 @@ class Worker extends core_1.Core {
|
|
|
79
79
|
return true;
|
|
80
80
|
})
|
|
81
81
|
.catch((err) => {
|
|
82
|
-
Worker.error(`Failed to push event to backend: ${err}`);
|
|
83
|
-
return false;
|
|
82
|
+
Worker.error(`Failed to push event to backend: ${err.message}`);
|
|
84
83
|
});
|
|
85
84
|
}
|
|
86
85
|
/**
|
|
@@ -92,8 +91,8 @@ class Worker extends core_1.Core {
|
|
|
92
91
|
*/
|
|
93
92
|
static async pushEventAsync(event, data = {}, ts = 0) {
|
|
94
93
|
if (!this.endpoint) {
|
|
95
|
-
Worker.
|
|
96
|
-
|
|
94
|
+
Worker.error(`Events endpoint is mandatory but missing! Cannot report job status to source.`);
|
|
95
|
+
throw new Error(`Events endpoint is mandatory but missing`);
|
|
97
96
|
}
|
|
98
97
|
try {
|
|
99
98
|
ts = ts === Date.now() ? Date.now() + 1 : Date.now();
|
|
@@ -105,14 +104,14 @@ class Worker extends core_1.Core {
|
|
|
105
104
|
ts,
|
|
106
105
|
};
|
|
107
106
|
const res = await axios_1.default.patch(Worker.endpoint, payload);
|
|
108
|
-
if (res.statusText === 'OK') {
|
|
107
|
+
if (res.statusText === 'OK' || res.status === 200) {
|
|
109
108
|
Worker.info(`Event pushed to backend: ${res.statusText}`);
|
|
110
109
|
return true;
|
|
111
110
|
}
|
|
112
111
|
}
|
|
113
112
|
catch (err) {
|
|
114
|
-
Worker.error(`Failed to push event to backend: ${err}`);
|
|
115
|
-
|
|
113
|
+
Worker.error(`Failed to push event to backend: ${err.message}`);
|
|
114
|
+
throw new Error(`Failed to push event to backend: ${err.message}`);
|
|
116
115
|
}
|
|
117
116
|
}
|
|
118
117
|
/**
|
package/dist/Worker.test.js
CHANGED
|
@@ -40,9 +40,8 @@ describe('Worker', () => {
|
|
|
40
40
|
});
|
|
41
41
|
});
|
|
42
42
|
describe('pushEvent', () => {
|
|
43
|
-
it('should
|
|
44
|
-
|
|
45
|
-
expect(result).toBe(false);
|
|
43
|
+
it('should throw error when endpoint is not set', () => {
|
|
44
|
+
expect(() => Worker_1.Worker.pushEvent('test-event')).toThrow('Events endpoint is mandatory but missing');
|
|
46
45
|
expect(mockedAxios.patch).not.toHaveBeenCalled();
|
|
47
46
|
});
|
|
48
47
|
it('should send event when endpoint is set', () => {
|
|
@@ -110,9 +109,8 @@ describe('Worker', () => {
|
|
|
110
109
|
});
|
|
111
110
|
});
|
|
112
111
|
describe('pushEventAsync', () => {
|
|
113
|
-
it('should
|
|
114
|
-
|
|
115
|
-
expect(result).toBe(false);
|
|
112
|
+
it('should throw error when endpoint is not set', async () => {
|
|
113
|
+
await expect(Worker_1.Worker.pushEventAsync('test-event')).rejects.toThrow('Events endpoint is mandatory but missing');
|
|
116
114
|
expect(mockedAxios.patch).not.toHaveBeenCalled();
|
|
117
115
|
});
|
|
118
116
|
it('should send event and return true on success', async () => {
|
|
@@ -130,11 +128,10 @@ describe('Worker', () => {
|
|
|
130
128
|
foo: 'bar',
|
|
131
129
|
}));
|
|
132
130
|
});
|
|
133
|
-
it('should
|
|
131
|
+
it('should throw error on axios error', async () => {
|
|
134
132
|
Worker_1.Worker.endpoint = 'https://api.example.com/events';
|
|
135
133
|
mockedAxios.patch.mockRejectedValue(new Error('Network error'));
|
|
136
|
-
|
|
137
|
-
expect(result).toBe(false);
|
|
134
|
+
await expect(Worker_1.Worker.pushEventAsync('test-event')).rejects.toThrow('Failed to push event to backend: Network error');
|
|
138
135
|
});
|
|
139
136
|
it('should handle non-OK status response', async () => {
|
|
140
137
|
Worker_1.Worker.endpoint = 'https://api.example.com/events';
|
package/package.json
CHANGED
package/src/FileSystem.test.ts
CHANGED
|
@@ -63,6 +63,13 @@ describe('FileSystem Utilities (Worker)', () => {
|
|
|
63
63
|
return Readable.from(Buffer.alloc(35 * 1024)) as any
|
|
64
64
|
})
|
|
65
65
|
|
|
66
|
+
jest.spyOn(fs, 'readFileSync').mockImplementation((p) => {
|
|
67
|
+
if (typeof p === 'string' && (p.endsWith('test.txt') || p.endsWith('small.mp4') || p.endsWith('large.mp4') || p.endsWith('large-fail.mp4') || p.endsWith('small-fail.mp4') || p.endsWith('large-sync-fail.mp4'))) {
|
|
68
|
+
return Buffer.alloc(35 * 1024)
|
|
69
|
+
}
|
|
70
|
+
return (jest.requireActual('node:fs').readFileSync)(p)
|
|
71
|
+
})
|
|
72
|
+
|
|
66
73
|
jest.spyOn(fs, 'existsSync').mockImplementation((p) => {
|
|
67
74
|
if (typeof p === 'string' && (p.endsWith('test.txt') || p.endsWith('small.mp4') || p.endsWith('large.mp4') || p.endsWith('large-fail.mp4') || p.endsWith('small-fail.mp4') || p.endsWith('large-sync-fail.mp4'))) {
|
|
68
75
|
return true
|
|
@@ -346,8 +353,8 @@ describe('FileSystem Utilities (Worker)', () => {
|
|
|
346
353
|
callback(null, mockMetadata)
|
|
347
354
|
});
|
|
348
355
|
|
|
349
|
-
// Make
|
|
350
|
-
jest.spyOn(fs, '
|
|
356
|
+
// Make readFileSync throw a synchronous error
|
|
357
|
+
jest.spyOn(fs, 'readFileSync').mockImplementationOnce(() => {
|
|
351
358
|
throw new Error('Sync stream error')
|
|
352
359
|
})
|
|
353
360
|
|
package/src/FileSystem.ts
CHANGED
|
@@ -116,74 +116,28 @@ export class FileSystem {
|
|
|
116
116
|
Worker.info(`Uploading file ${filename} to ${meta.uploadUrl}`)
|
|
117
117
|
const { size } = fs.statSync(filename)
|
|
118
118
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
},
|
|
130
|
-
} as any)
|
|
131
|
-
.then(() => resolve({ ...meta, size, uploadUrl: undefined }))
|
|
132
|
-
.catch((err) => {
|
|
133
|
-
Worker.error(
|
|
134
|
-
`An error occured while uploading ${filename}: ${err.message}`
|
|
135
|
-
)
|
|
136
|
-
reject(err)
|
|
137
|
-
})
|
|
119
|
+
try {
|
|
120
|
+
Worker.info(`Uploading file ${filename} with size ${size} bytes`)
|
|
121
|
+
const fileBuffer = fs.readFileSync(filename)
|
|
122
|
+
|
|
123
|
+
const res = await fetch(meta.uploadUrl, {
|
|
124
|
+
method: 'PUT',
|
|
125
|
+
body: fileBuffer,
|
|
126
|
+
headers: {
|
|
127
|
+
'Content-Type': meta.contentType || mime,
|
|
128
|
+
},
|
|
138
129
|
})
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
return new Promise((resolve, reject) => {
|
|
142
|
-
try {
|
|
143
|
-
let done = 0 // total bytes uploaded
|
|
144
|
-
let prev = 0 // latest value of done stored when % done was displayed
|
|
145
|
-
const { size } = fs.statSync(filename)
|
|
146
|
-
const readStream = fs.createReadStream(filename)
|
|
147
130
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
done += data.length
|
|
152
|
-
if (done - prev >= size / 20) {
|
|
153
|
-
// only display message when 5% more has been uploaded
|
|
154
|
-
Worker.info(
|
|
155
|
-
`${((done / size) * 100).toFixed(2)}% - ${(
|
|
156
|
-
done /
|
|
157
|
-
(1024 * 1024)
|
|
158
|
-
).toFixed(2)}MB / ${sizeMB}MB`
|
|
159
|
-
)
|
|
160
|
-
prev = done
|
|
161
|
-
}
|
|
162
|
-
})
|
|
163
|
-
|
|
164
|
-
Worker.info(`Uploading file ${filename} with size ${size} bytes`)
|
|
165
|
-
fetch(meta.uploadUrl, {
|
|
166
|
-
method: 'PUT',
|
|
167
|
-
mode: 'cors',
|
|
168
|
-
duplex: 'half',
|
|
169
|
-
body: readStream,
|
|
170
|
-
headers: {
|
|
171
|
-
'Content-Type': meta.contentType || mime,
|
|
172
|
-
'Content-length': String(size),
|
|
173
|
-
},
|
|
174
|
-
} as any)
|
|
175
|
-
.then(() => resolve({ ...meta, size, uploadUrl: undefined }))
|
|
176
|
-
.catch((err) => {
|
|
177
|
-
Worker.error(
|
|
178
|
-
`An error occured while uploading ${filename}: ${err.message}`
|
|
179
|
-
)
|
|
180
|
-
reject(err)
|
|
181
|
-
})
|
|
182
|
-
} catch (err) {
|
|
183
|
-
Worker.error(err)
|
|
184
|
-
reject(err)
|
|
131
|
+
if (res && res.ok === false) {
|
|
132
|
+
const errorText = typeof res.text === 'function' ? await res.text().catch(() => '') : ''
|
|
133
|
+
throw new Error(`HTTP upload failed with status ${res.status || 'unknown'}: ${errorText}`)
|
|
185
134
|
}
|
|
186
|
-
|
|
135
|
+
|
|
136
|
+
return { ...meta, size, uploadUrl: undefined }
|
|
137
|
+
} catch (err: any) {
|
|
138
|
+
Worker.error(`An error occured while uploading ${filename}: ${err.message}`)
|
|
139
|
+
throw err
|
|
140
|
+
}
|
|
187
141
|
}
|
|
188
142
|
|
|
189
143
|
/**
|
package/src/Helpers.ts
CHANGED
|
@@ -5,8 +5,15 @@ import path from 'node:path'
|
|
|
5
5
|
* General utility class providing common static helpers for workers.
|
|
6
6
|
*/
|
|
7
7
|
export class Helpers {
|
|
8
|
+
private static _ffmpegPathPromise: Promise<string> | null = null
|
|
9
|
+
|
|
8
10
|
/** Default absolute path to the system's FFmpeg binary. */
|
|
9
|
-
static FFMPEG
|
|
11
|
+
static get FFMPEG(): Promise<string> {
|
|
12
|
+
if (!this._ffmpegPathPromise) {
|
|
13
|
+
this._ffmpegPathPromise = Worker.getSystemCommandPath('ffmpeg').catch(() => 'ffmpeg')
|
|
14
|
+
}
|
|
15
|
+
return this._ffmpegPathPromise
|
|
16
|
+
}
|
|
10
17
|
|
|
11
18
|
/**
|
|
12
19
|
* Generate a thubnail from a video file at given frame position
|
package/src/Worker.test.ts
CHANGED
|
@@ -42,9 +42,8 @@ describe('Worker', () => {
|
|
|
42
42
|
})
|
|
43
43
|
|
|
44
44
|
describe('pushEvent', () => {
|
|
45
|
-
it('should
|
|
46
|
-
|
|
47
|
-
expect(result).toBe(false)
|
|
45
|
+
it('should throw error when endpoint is not set', () => {
|
|
46
|
+
expect(() => Worker.pushEvent('test-event')).toThrow('Events endpoint is mandatory but missing')
|
|
48
47
|
expect(mockedAxios.patch).not.toHaveBeenCalled()
|
|
49
48
|
})
|
|
50
49
|
|
|
@@ -145,9 +144,8 @@ describe('Worker', () => {
|
|
|
145
144
|
})
|
|
146
145
|
|
|
147
146
|
describe('pushEventAsync', () => {
|
|
148
|
-
it('should
|
|
149
|
-
|
|
150
|
-
expect(result).toBe(false)
|
|
147
|
+
it('should throw error when endpoint is not set', async () => {
|
|
148
|
+
await expect(Worker.pushEventAsync('test-event')).rejects.toThrow('Events endpoint is mandatory but missing')
|
|
151
149
|
expect(mockedAxios.patch).not.toHaveBeenCalled()
|
|
152
150
|
})
|
|
153
151
|
|
|
@@ -173,14 +171,12 @@ describe('Worker', () => {
|
|
|
173
171
|
)
|
|
174
172
|
})
|
|
175
173
|
|
|
176
|
-
it('should
|
|
174
|
+
it('should throw error on axios error', async () => {
|
|
177
175
|
Worker.endpoint = 'https://api.example.com/events'
|
|
178
176
|
|
|
179
177
|
mockedAxios.patch.mockRejectedValue(new Error('Network error'))
|
|
180
178
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
expect(result).toBe(false)
|
|
179
|
+
await expect(Worker.pushEventAsync('test-event')).rejects.toThrow('Failed to push event to backend: Network error')
|
|
184
180
|
})
|
|
185
181
|
|
|
186
182
|
it('should handle non-OK status response', async () => {
|
package/src/Worker.ts
CHANGED
|
@@ -66,8 +66,8 @@ export class Worker extends Core {
|
|
|
66
66
|
*/
|
|
67
67
|
static pushEvent(event: string, data = {}, ts = 0) {
|
|
68
68
|
if (!this.endpoint) {
|
|
69
|
-
Worker.
|
|
70
|
-
|
|
69
|
+
Worker.error(`Events endpoint is mandatory but missing! Cannot report job status to source.`)
|
|
70
|
+
throw new Error(`Events endpoint is mandatory but missing`)
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
ts = ts === Date.now() ? Date.now() + 1 : Date.now()
|
|
@@ -89,8 +89,7 @@ export class Worker extends Core {
|
|
|
89
89
|
return true
|
|
90
90
|
})
|
|
91
91
|
.catch((err) => {
|
|
92
|
-
Worker.error(`Failed to push event to backend: ${err}`)
|
|
93
|
-
return false
|
|
92
|
+
Worker.error(`Failed to push event to backend: ${err.message}`)
|
|
94
93
|
})
|
|
95
94
|
}
|
|
96
95
|
|
|
@@ -103,8 +102,8 @@ export class Worker extends Core {
|
|
|
103
102
|
*/
|
|
104
103
|
static async pushEventAsync(event: string, data = {}, ts = 0) {
|
|
105
104
|
if (!this.endpoint) {
|
|
106
|
-
Worker.
|
|
107
|
-
|
|
105
|
+
Worker.error(`Events endpoint is mandatory but missing! Cannot report job status to source.`)
|
|
106
|
+
throw new Error(`Events endpoint is mandatory but missing`)
|
|
108
107
|
}
|
|
109
108
|
|
|
110
109
|
try {
|
|
@@ -119,13 +118,13 @@ export class Worker extends Core {
|
|
|
119
118
|
|
|
120
119
|
const res = await axios.patch(Worker.endpoint, payload)
|
|
121
120
|
|
|
122
|
-
if (res.statusText === 'OK') {
|
|
121
|
+
if (res.statusText === 'OK' || res.status === 200) {
|
|
123
122
|
Worker.info(`Event pushed to backend: ${res.statusText}`)
|
|
124
123
|
return true
|
|
125
124
|
}
|
|
126
|
-
} catch (err) {
|
|
127
|
-
Worker.error(`Failed to push event to backend: ${err}`)
|
|
128
|
-
|
|
125
|
+
} catch (err: any) {
|
|
126
|
+
Worker.error(`Failed to push event to backend: ${err.message}`)
|
|
127
|
+
throw new Error(`Failed to push event to backend: ${err.message}`)
|
|
129
128
|
}
|
|
130
129
|
}
|
|
131
130
|
|