@jsreport/jsreport-core 4.6.0 → 4.7.0
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/README.md +4 -0
- package/lib/main/profiler.js +4 -4
- package/lib/shared/createError.js +45 -6
- package/lib/worker/defaultProxyExtend.js +38 -0
- package/lib/worker/render/engineStream.js +2 -11
- package/lib/worker/reporter.js +2 -1
- package/lib/worker/workerHandler.js +2 -2
- package/package.json +4 -4
package/README.md
CHANGED
package/lib/main/profiler.js
CHANGED
|
@@ -441,14 +441,14 @@ module.exports = (reporter) => {
|
|
|
441
441
|
clearInterval(profilesCleanupInterval)
|
|
442
442
|
}
|
|
443
443
|
|
|
444
|
-
if (profilesCleanupInterval) {
|
|
445
|
-
clearInterval(profilesCleanupInterval)
|
|
446
|
-
}
|
|
447
|
-
|
|
448
444
|
if (fullModeDurationCheckInterval) {
|
|
449
445
|
clearInterval(fullModeDurationCheckInterval)
|
|
450
446
|
}
|
|
451
447
|
|
|
448
|
+
if (profilesCancelingCheckInterval) {
|
|
449
|
+
clearInterval(profilesCancelingCheckInterval)
|
|
450
|
+
}
|
|
451
|
+
|
|
452
452
|
try {
|
|
453
453
|
const runningRequests = [...reporter.runningRequests.map.values()]
|
|
454
454
|
await reporter.documentStore.collection('profiles').update({
|
|
@@ -25,15 +25,37 @@ module.exports = function (message, options = {}) {
|
|
|
25
25
|
error.weak = originalNormalized.weak
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
const initialMsg = error.message == null || error.message === '' ? '' : error.message
|
|
29
|
+
const [messages, stacks] = getErrorMessagesAndStacks(originalNormalized)
|
|
30
|
+
|
|
31
|
+
if (initialMsg !== '') {
|
|
32
|
+
messages.unshift(initialMsg)
|
|
32
33
|
}
|
|
33
34
|
|
|
35
|
+
error.message = messages.reduce((acu, msg) => {
|
|
36
|
+
if (acu === '') {
|
|
37
|
+
acu += msg
|
|
38
|
+
} else {
|
|
39
|
+
acu += `\n(because) ${lowerCaseFirstLetter(msg)}`
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return acu
|
|
43
|
+
}, '')
|
|
44
|
+
|
|
34
45
|
// stack is printed in reverse order (from cause to more high level error)
|
|
35
|
-
if (error.stack != null && originalNormalized.stack != null) {
|
|
36
|
-
|
|
46
|
+
if (error.stack != null && originalNormalized.stack != null && stacks.length > 0) {
|
|
47
|
+
stacks.unshift(error.stack)
|
|
48
|
+
stacks.reverse()
|
|
49
|
+
|
|
50
|
+
error.stack = stacks.reduce((acu, stack) => {
|
|
51
|
+
if (acu === '') {
|
|
52
|
+
acu += stack
|
|
53
|
+
} else {
|
|
54
|
+
acu += `\nwrapped by:\n${stack}`
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return acu
|
|
58
|
+
}, '')
|
|
37
59
|
}
|
|
38
60
|
}
|
|
39
61
|
}
|
|
@@ -49,6 +71,23 @@ module.exports = function (message, options = {}) {
|
|
|
49
71
|
return error
|
|
50
72
|
}
|
|
51
73
|
|
|
74
|
+
function getErrorMessagesAndStacks (err) {
|
|
75
|
+
let currentErr = err
|
|
76
|
+
const messages = []
|
|
77
|
+
const stacks = []
|
|
78
|
+
|
|
79
|
+
while (currentErr != null) {
|
|
80
|
+
if (currentErr.message) {
|
|
81
|
+
messages.push(currentErr.message)
|
|
82
|
+
stacks.push(currentErr.stack ?? '(no stack available)')
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
currentErr = currentErr.cause
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return [messages, stacks]
|
|
89
|
+
}
|
|
90
|
+
|
|
52
91
|
function lowerCaseFirstLetter (str) {
|
|
53
92
|
if (str === '' || typeof str !== 'string') {
|
|
54
93
|
return str
|
|
@@ -41,4 +41,42 @@ module.exports = (reporter) => (proxy, req) => {
|
|
|
41
41
|
return reporter.folders.resolveEntityPath(entity, es, req)
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
|
+
|
|
45
|
+
// expose tempfile functions
|
|
46
|
+
const createTempFileFns = [
|
|
47
|
+
'getTempFilePath', 'openTempFile', 'writeTempFileSync', 'writeTempFile',
|
|
48
|
+
'writeTempFileStream', 'copyFileToTempFile'
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
const restOfTempFileFns = [
|
|
52
|
+
'readTempFileSync', 'readTempFile', 'readTempFileStream'
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
const allFns = [
|
|
56
|
+
...createTempFileFns,
|
|
57
|
+
...restOfTempFileFns
|
|
58
|
+
]
|
|
59
|
+
|
|
60
|
+
for (const fnName of allFns) {
|
|
61
|
+
const shouldLimitCreation = createTempFileFns.includes(fnName)
|
|
62
|
+
|
|
63
|
+
proxy[fnName] = (...args) => {
|
|
64
|
+
if (shouldLimitCreation) {
|
|
65
|
+
// limiting the number of temp files to avoid breaking server, otherwise I see no
|
|
66
|
+
// reason why having more than 1000 calls per req should be valid usecase
|
|
67
|
+
const counter = reporter.runningRequests.keyValueStore.get('tmp-file-counter', req) || 0
|
|
68
|
+
|
|
69
|
+
if (counter > 1000) {
|
|
70
|
+
throw reporter.createError('Reached maximum limit of tmp file calls in sandbox', {
|
|
71
|
+
weak: true,
|
|
72
|
+
statusCode: 400
|
|
73
|
+
})
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
reporter.runningRequests.keyValueStore.set('tmp-file-counter', counter + 1, req)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return reporter[fnName](...args)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
44
82
|
}
|
|
@@ -57,22 +57,13 @@ module.exports = (reporter) => {
|
|
|
57
57
|
}) => {
|
|
58
58
|
if (proxy.templatingEngines) {
|
|
59
59
|
proxy.templatingEngines.createStream = async (opts = {}) => {
|
|
60
|
-
// limiting the number of temp files to avoid breaking server, otherwise I see no reason why having more than 1000 calls per req should be valid usecase
|
|
61
|
-
const counter = reporter.runningRequests.keyValueStore.get('engine-stream-counter', req) || 0
|
|
62
|
-
if (counter > 1000) {
|
|
63
|
-
throw reporter.createError('Reached maximum limit of templatingEngine.createStream calls', {
|
|
64
|
-
weak: true,
|
|
65
|
-
statusCode: 400
|
|
66
|
-
})
|
|
67
|
-
}
|
|
68
|
-
reporter.runningRequests.keyValueStore.set('engine-stream-counter', counter + 1, req)
|
|
69
|
-
|
|
70
60
|
req.context.engineStreamEnabled = true
|
|
71
61
|
|
|
72
62
|
const bufferSize = bytes(opts.bufferSize || '10mb')
|
|
73
63
|
let buf = ''
|
|
74
64
|
|
|
75
|
-
|
|
65
|
+
// using proxy.openTempFile to respect limits of temp files in sandbox
|
|
66
|
+
const { fileHandle, filename } = await proxy.openTempFile((uuid) => `${uuid}.stream`, 'a')
|
|
76
67
|
proxy.templatingEngines.addFinishListener(() => fileHandle.close().catch((e) => reporter.logger.error('Failed to close temp file handle', e, req)))
|
|
77
68
|
|
|
78
69
|
return {
|
package/lib/worker/reporter.js
CHANGED
|
@@ -14,10 +14,11 @@ const engineStream = require('./render/engineStream.js')
|
|
|
14
14
|
|
|
15
15
|
class WorkerReporter extends Reporter {
|
|
16
16
|
constructor (workerData, executeMain) {
|
|
17
|
-
const { options, documentStore, extensionsDefs } = workerData
|
|
17
|
+
const { options, documentStore, extensionsDefs, workerId } = workerData
|
|
18
18
|
|
|
19
19
|
super(options)
|
|
20
20
|
|
|
21
|
+
this.workerId = workerId
|
|
21
22
|
this._executeMain = executeMain
|
|
22
23
|
this._initialized = false
|
|
23
24
|
this._lockedDown = false
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
const WorkerReporter = require('./reporter')
|
|
2
2
|
const omit = require('lodash.omit')
|
|
3
3
|
|
|
4
|
-
module.exports = (userInitData, { executeMain, convertUint8ArrayToBuffer }) => {
|
|
5
|
-
const reporter = new WorkerReporter(userInitData, async (actionName, data, req) => {
|
|
4
|
+
module.exports = (userInitData, { executeMain, convertUint8ArrayToBuffer, workerId }) => {
|
|
5
|
+
const reporter = new WorkerReporter({ ...userInitData, workerId }, async (actionName, data, req) => {
|
|
6
6
|
const actionRes = await executeMain({
|
|
7
7
|
actionName,
|
|
8
8
|
data
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsreport/jsreport-core",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.7.0",
|
|
4
4
|
"description": "javascript based business reporting",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"report",
|
|
@@ -40,11 +40,11 @@
|
|
|
40
40
|
"@babel/parser": "7.23.5",
|
|
41
41
|
"@babel/traverse": "7.23.5",
|
|
42
42
|
"@colors/colors": "1.5.0",
|
|
43
|
-
"@jsreport/advanced-workers": "2.0
|
|
43
|
+
"@jsreport/advanced-workers": "2.1.0",
|
|
44
44
|
"@jsreport/mingo": "2.4.1",
|
|
45
45
|
"@jsreport/reap": "0.1.0",
|
|
46
|
-
"@jsreport/serializator": "1.0.
|
|
47
|
-
"@jsreport/ses": "1.
|
|
46
|
+
"@jsreport/serializator": "1.0.1",
|
|
47
|
+
"@jsreport/ses": "1.2.0",
|
|
48
48
|
"ajv": "6.12.6",
|
|
49
49
|
"app-root-path": "3.0.0",
|
|
50
50
|
"bytes": "3.1.2",
|