Skip to content

Commit 1162c29

Browse files
abbesBenayachePierreJeanjacquot
authored andcommitted
refactor: improve bulk processing structure and error handling
- Move index parameter into params object in processProtectedData - Compute datasetFilename from index inside processProtectedData - Move result.json writing to start function (from processProtectedData) - Change result.txt to result.json for better semantic accuracy - Update bulk processing structure: total-processed → total-count, protected-data-results → results, remove status field - Rename dataset to protected-data in results and error messages - Improve error messages with 'Cause:' prefix for bulk processing errors - Update iexec dependency to ^8.22.0 - Update tests to match new structure
1 parent 09aeba6 commit 1162c29

File tree

3 files changed

+85
-88
lines changed

3 files changed

+85
-88
lines changed

dapp/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
"eslint-config-prettier": "^9.0.0",
3737
"eslint-plugin-import": "^2.28.1",
3838
"eslint-plugin-sonarjs": "^0.21.0",
39-
"iexec": "^8.2.1",
39+
"iexec": "^8.22.0",
4040
"jest": "^29.7.0",
4141
"prettier": "^2.8.8"
4242
}

dapp/src/sendEmail.js

Lines changed: 50 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,15 @@ async function writeTaskOutput(path, message) {
2828
}
2929
}
3030

31-
async function processProtectedData(
31+
async function processProtectedData({
3232
index,
33-
{
34-
IEXEC_IN,
35-
IEXEC_OUT,
36-
appDeveloperSecret,
37-
requesterSecret,
38-
datasetFilename = null,
39-
}
40-
) {
33+
IEXEC_IN,
34+
appDeveloperSecret,
35+
requesterSecret,
36+
}) {
37+
const datasetFilename =
38+
index > 0 ? process.env[`IEXEC_DATASET_${index}_FILENAME`] : null;
39+
4140
// Parse the protected data
4241
let protectedData;
4342
try {
@@ -110,13 +109,6 @@ async function processProtectedData(
110109
senderName: requesterSecret.senderName,
111110
});
112111

113-
if (index === 0) {
114-
await writeTaskOutput(
115-
`${IEXEC_OUT}/result.txt`,
116-
JSON.stringify(response, null, 2)
117-
);
118-
}
119-
120112
return { index, response, isEmailValidated };
121113
}
122114

@@ -159,76 +151,82 @@ async function start() {
159151
const bulkSize = parseInt(IEXEC_BULK_SLICE_SIZE, 10) || 0;
160152
const results = [];
161153

154+
// Process multiple protected data
162155
if (bulkSize > 0) {
163-
// Process multiple protected data
164156
const promises = [];
165-
for (let i = 1; i <= bulkSize; i += 1) {
166-
const datasetFilename = process.env[`IEXEC_DATASET_${i}_FILENAME`];
167-
168-
const promise = processProtectedData(i, {
157+
for (let index = 1; index <= bulkSize; index += 1) {
158+
const promise = processProtectedData({
159+
index,
169160
IEXEC_IN,
170-
IEXEC_OUT: workerEnv.IEXEC_OUT,
171161
appDeveloperSecret,
172162
requesterSecret,
173-
datasetFilename,
174163
})
175164
.then((result) => result)
176-
.catch((error) => ({
177-
index: i,
178-
resultFileName: datasetFilename
179-
? `${datasetFilename}.txt`
180-
: `dataset-${i}.txt`,
181-
response: {
182-
status: 500,
183-
message: `Failed to process dataset ${i}: ${error.message}`,
184-
},
185-
}));
165+
.catch((error) => {
166+
const datasetFilename =
167+
process.env[`IEXEC_DATASET_${index}_FILENAME`];
168+
return {
169+
index,
170+
resultFileName: datasetFilename
171+
? `${datasetFilename}.txt`
172+
: `dataset-${index}.txt`,
173+
response: {
174+
status: 500,
175+
message: `Failed to process protected-data ${index}. Cause: ${error.message}`,
176+
},
177+
};
178+
});
186179

187180
promises.push(promise);
188181
}
189182

190183
const bulkResults = await Promise.all(promises);
191184
results.push(...bulkResults);
192-
} else {
193-
// Process single protected data
194-
const result = await processProtectedData(0, {
195-
IEXEC_IN,
196-
IEXEC_OUT: workerEnv.IEXEC_OUT,
197-
appDeveloperSecret,
198-
requesterSecret,
199-
});
200185

201-
results.push(result);
202-
}
203-
204-
// Create result.txt for bulk processing
205-
if (bulkSize > 0) {
186+
// Write result.json for bulk processing
206187
const successCount = results.filter(
207188
(r) => r.response.status === 200
208189
).length;
209190
const errorCount = results.filter((r) => r.response.status !== 200).length;
210191

211192
const bulkResult = {
212193
message: `Bulk processing completed: ${successCount} successful, ${errorCount} failed`,
213-
status: 200,
214-
'total-processed': results.length,
194+
'total-count': results.length,
215195
'success-count': successCount,
216196
'error-count': errorCount,
217-
'protected-data-results': results.map((r) => ({
197+
results: results.map((r) => ({
218198
index: r.index,
219-
protectedData: process.env[`IEXEC_DATASET_${r.index}_FILENAME`],
199+
'protected-data':
200+
process.env[`IEXEC_DATASET_${r.index}_FILENAME`] ||
201+
`dataset-${r.index}`,
220202
response: r.response,
221203
})),
222204
};
223205

224206
await writeTaskOutput(
225-
`${workerEnv.IEXEC_OUT}/result.txt`,
207+
`${workerEnv.IEXEC_OUT}/result.json`,
226208
JSON.stringify(bulkResult, null, 2)
227209
);
210+
} else {
211+
// Process single protected data
212+
const result = await processProtectedData({
213+
index: 0,
214+
IEXEC_IN,
215+
appDeveloperSecret,
216+
requesterSecret,
217+
});
218+
219+
results.push(result);
220+
221+
await writeTaskOutput(
222+
`${workerEnv.IEXEC_OUT}/result.json`,
223+
JSON.stringify(result.response, null, 2)
224+
);
228225
}
229226

227+
// Generate computed.json - same format for both single and bulk
230228
const computedData = {
231-
'deterministic-output-path': `${workerEnv.IEXEC_OUT}/result.txt`,
229+
'deterministic-output-path': `${workerEnv.IEXEC_OUT}/result.json`,
232230
};
233231

234232
// Add callback data for single processing if useCallback is enabled

dapp/tests/e2e/app.test.js

Lines changed: 34 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -390,27 +390,27 @@ describe('sendEmail', () => {
390390
await expect(start()).resolves.toBeUndefined();
391391

392392
const { IEXEC_OUT } = process.env;
393-
const resultTxt = await fsPromises.readFile(
394-
path.join(IEXEC_OUT, 'result.txt'),
393+
const resultJson = await fsPromises.readFile(
394+
path.join(IEXEC_OUT, 'result.json'),
395395
'utf-8'
396396
);
397397
const computedJson = await fsPromises.readFile(
398398
path.join(IEXEC_OUT, 'computed.json'),
399399
'utf-8'
400400
);
401-
expect(JSON.parse(resultTxt)).toStrictEqual({
401+
expect(JSON.parse(resultJson)).toStrictEqual({
402402
message: 'Your email has been sent successfully.',
403403
status: 200,
404404
});
405405
if (requesterSecret.useCallback) {
406406
expect(JSON.parse(computedJson)).toStrictEqual({
407407
'callback-data':
408408
'0x0000000000000000000000000000000000000000000000000000000000000001',
409-
'deterministic-output-path': `${IEXEC_OUT}/result.txt`,
409+
'deterministic-output-path': `${IEXEC_OUT}/result.json`,
410410
});
411411
} else {
412412
expect(JSON.parse(computedJson)).toStrictEqual({
413-
'deterministic-output-path': `${IEXEC_OUT}/result.txt`,
413+
'deterministic-output-path': `${IEXEC_OUT}/result.json`,
414414
});
415415
}
416416
// output should not contain extra files
@@ -478,17 +478,17 @@ describe('sendEmail', () => {
478478

479479
// Check that bulk processing was attempted and completed
480480
const { IEXEC_OUT } = process.env;
481-
const resultTxt = await fsPromises.readFile(
482-
path.join(IEXEC_OUT, 'result.txt'),
481+
const resultJson = await fsPromises.readFile(
482+
path.join(IEXEC_OUT, 'result.json'),
483483
'utf-8'
484484
);
485-
const result = JSON.parse(resultTxt);
485+
const result = JSON.parse(resultJson);
486486

487-
expect(result).toHaveProperty('total-processed', 2);
487+
expect(result).toHaveProperty('total-count', 2);
488488
expect(result).toHaveProperty('success-count');
489489
expect(result).toHaveProperty('error-count');
490-
expect(result).toHaveProperty('protected-data-results');
491-
expect(result['protected-data-results']).toHaveLength(2);
490+
expect(result).toHaveProperty('results');
491+
expect(result.results).toHaveLength(2);
492492
});
493493

494494
it('should handle mixed valid and invalid datasets', async () => {
@@ -499,20 +499,20 @@ describe('sendEmail', () => {
499499
await expect(start()).resolves.toBeUndefined();
500500

501501
const { IEXEC_OUT } = process.env;
502-
const resultTxt = await fsPromises.readFile(
503-
path.join(IEXEC_OUT, 'result.txt'),
502+
const resultJson = await fsPromises.readFile(
503+
path.join(IEXEC_OUT, 'result.json'),
504504
'utf-8'
505505
);
506-
const result = JSON.parse(resultTxt);
506+
const result = JSON.parse(resultJson);
507507

508-
expect(result).toHaveProperty('total-processed', 2);
509-
expect(result['protected-data-results']).toHaveLength(2);
508+
expect(result).toHaveProperty('total-count', 2);
509+
expect(result.results).toHaveLength(2);
510510

511511
// Should have both successes and errors
512-
const successResults = result['protected-data-results'].filter(
512+
const successResults = result.results.filter(
513513
(r) => r.response.status === 200
514514
);
515-
const errorResults = result['protected-data-results'].filter(
515+
const errorResults = result.results.filter(
516516
(r) => r.response.status !== 200
517517
);
518518

@@ -591,31 +591,30 @@ describe('sendEmail', () => {
591591
await expect(start()).resolves.toBeUndefined();
592592

593593
const { IEXEC_OUT } = process.env;
594-
const resultTxt = await fsPromises.readFile(
595-
path.join(IEXEC_OUT, 'result.txt'),
594+
const resultJson = await fsPromises.readFile(
595+
path.join(IEXEC_OUT, 'result.json'),
596596
'utf-8'
597597
);
598598
const computedJson = await fsPromises.readFile(
599599
path.join(IEXEC_OUT, 'computed.json'),
600600
'utf-8'
601601
);
602602

603-
const result = JSON.parse(resultTxt);
603+
const result = JSON.parse(resultJson);
604604
const computed = JSON.parse(computedJson);
605605

606606
// Verify bulk processing result structure
607607
expect(result).toHaveProperty('message');
608-
expect(result).toHaveProperty('status', 200);
609-
expect(result).toHaveProperty('total-processed', 2);
608+
expect(result).toHaveProperty('total-count', 2);
610609
expect(result).toHaveProperty('success-count', 2);
611610
expect(result).toHaveProperty('error-count', 0);
612-
expect(result).toHaveProperty('protected-data-results');
613-
expect(result['protected-data-results']).toHaveLength(2);
611+
expect(result).toHaveProperty('results');
612+
expect(result.results).toHaveLength(2);
614613

615614
// Verify each protected data result
616-
result['protected-data-results'].forEach((datasetResult, index) => {
615+
result.results.forEach((datasetResult, index) => {
617616
expect(datasetResult).toHaveProperty('index', index + 1);
618-
expect(datasetResult).toHaveProperty('protectedData');
617+
expect(datasetResult).toHaveProperty('protected-data');
619618
expect(datasetResult).toHaveProperty('response');
620619
expect(datasetResult.response).toHaveProperty('status', 200);
621620
expect(datasetResult.response).toHaveProperty('message');
@@ -624,13 +623,13 @@ describe('sendEmail', () => {
624623
// Verify computed.json structure
625624
expect(computed).toHaveProperty('deterministic-output-path');
626625
expect(computed['deterministic-output-path']).toBe(
627-
`${IEXEC_OUT}/result.txt`
626+
`${IEXEC_OUT}/result.json`
628627
);
629628

630629
// Verify no extra files were created
631630
const out = await fsPromises.readdir(IEXEC_OUT);
632631
expect(out.length).toBe(2);
633-
expect(out).toContain('result.txt');
632+
expect(out).toContain('result.json');
634633
expect(out).toContain('computed.json');
635634
});
636635

@@ -641,16 +640,16 @@ describe('sendEmail', () => {
641640
await expect(start()).resolves.toBeUndefined();
642641

643642
const { IEXEC_OUT } = process.env;
644-
const resultTxt = await fsPromises.readFile(
645-
path.join(IEXEC_OUT, 'result.txt'),
643+
const resultJson = await fsPromises.readFile(
644+
path.join(IEXEC_OUT, 'result.json'),
646645
'utf-8'
647646
);
648647
const computedJson = await fsPromises.readFile(
649648
path.join(IEXEC_OUT, 'computed.json'),
650649
'utf-8'
651650
);
652651

653-
const result = JSON.parse(resultTxt);
652+
const result = JSON.parse(resultJson);
654653
const computed = JSON.parse(computedJson);
655654

656655
// Verify single processing result structure (not bulk)
@@ -659,13 +658,13 @@ describe('sendEmail', () => {
659658
'Your email has been sent successfully.'
660659
);
661660
expect(result).toHaveProperty('status', 200);
662-
expect(result).not.toHaveProperty('total-processed');
663-
expect(result).not.toHaveProperty('protected-data-results');
661+
expect(result).not.toHaveProperty('total-count');
662+
expect(result).not.toHaveProperty('results');
664663

665664
// Verify computed.json structure
666665
expect(computed).toHaveProperty('deterministic-output-path');
667666
expect(computed['deterministic-output-path']).toBe(
668-
`${IEXEC_OUT}/result.txt`
667+
`${IEXEC_OUT}/result.json`
669668
);
670669
});
671670
});

0 commit comments

Comments
 (0)