Hi all,
Trying to run _addFile_ on a meteor method (server) gives me this error:
UnhandledPromiseRejectionWarning: RangeError: Maximum call stack size exceeded
I have run the _addFile_ method using async/await; without async/await; and with
Async (meteorhacks:async). I always get same error.
Note: the document is saved on the collection in mongo. But the error occurs and the
method does not return normally to the client.
This is my collection:
import { FilesCollection } from 'meteor/ostrio:files';
import SimpleSchema from 'simpl-schema';
const mySchema = {
...FilesCollection.schema,
};
export const FluentReports = new FilesCollection({
collectionName: 'fluentReports',
allowClientCode: false, // Disallow remove files from Client
debug: true
});
FluentReports.collection.attachSchema(new SimpleSchema(mySchema));
This is my meteor method:
Meteor.methods({
'requerimientos.reports.general_4'() {
const user = Meteor.user();
const fileName = `req.report.general.${user._id}.pdf`;
let finalPath = path.join(process.env.PWD, `/.temp`, fileName);
finalPath = finalPath.replace(/\\/g, "/");
let response = null;
response = Async.runSync(function(done) {
Promise.resolve(
FluentReports.addFile(finalPath, {
fileName: fileName,
type: 'pdf',
fileId: new Mongo.ObjectID()._str,
meta: {owner: this.userId, createdAt: new Date()}
})
)
.then(function(result) { done(null, result); })
.catch(function (err) { done(err, null); })
.done();
});
if (response.error) {
console.log(`An error occurred: ${response.error.message}`)
}
return {
error: false,
message: "Ok, el reporte ha sido agregado a meteor-files.",
result: response
}
}})
Version of Meteor-Files you're experiencing this issue: ostrio:[email protected]
Version of Meteor you're experiencing this issue: [email protected]
Where this issue appears? OS (Mac/Win/Linux)? Browser name and its version?
Windows 10 / Chrome: Version 81.0.4044.113 (Official Build) (64-bit)
Is it Client or Server issue?
Server - _addFile_ on meteor method
This is what is in the console after the error occurs:
I20200423-16:47:47.561(-4)? [FilesCollection] [addFile(C:/requerimientos/.temp/req.report.general.67Qjx32kS7bmhWcfp.pdf)]
W20200423-16:47:52.497(-4)? (STDERR) (node:12008) UnhandledPromiseRejectionWarning: RangeError: Maximum call stack size exceeded
W20200423-16:47:52.498(-4)? (STDERR) at Function.[Symbol.hasInstance] (<anonymous>)
W20200423-16:47:52.499(-4)? (STDERR) at Object.EJSON.isBinary (packages/ejson/ejson.js:426:54)
W20200423-16:47:52.499(-4)? (STDERR) at Object.EJSON.clone (packages/ejson/ejson.js:571:13)
W20200423-16:47:52.499(-4)? (STDERR) at packages/ejson/ejson.js:600:22
W20200423-16:47:52.500(-4)? (STDERR) at Array.forEach (<anonymous>)
W20200423-16:47:52.500(-4)? (STDERR) at Object.EJSON.clone (packages/ejson/ejson.js:599:13)
W20200423-16:47:52.501(-4)? (STDERR) at packages/ejson/ejson.js:600:22
W20200423-16:47:52.501(-4)? (STDERR) at Array.forEach (<anonymous>)
W20200423-16:47:52.501(-4)? (STDERR) at Object.EJSON.clone (packages/ejson/ejson.js:599:13)
W20200423-16:47:52.502(-4)? (STDERR) at packages/ejson/ejson.js:600:22
W20200423-16:47:52.502(-4)? (STDERR) at Array.forEach (<anonymous>)
W20200423-16:47:52.502(-4)? (STDERR) at Object.EJSON.clone (packages/ejson/ejson.js:599:13)
W20200423-16:47:52.503(-4)? (STDERR) at packages/ejson/ejson.js:600:22
W20200423-16:47:52.503(-4)? (STDERR) at Array.forEach (<anonymous>)
W20200423-16:47:52.504(-4)? (STDERR) at Object.EJSON.clone (packages/ejson/ejson.js:599:13)
W20200423-16:47:52.504(-4)? (STDERR) at packages/ejson/ejson.js:600:22
W20200423-16:47:52.504(-4)? (STDERR) (node:12008) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 4)
I20200423-16:47:52.858(-4)? [FilesCollection] [addFile]: req.report.general.67Qjx32kS7bmhWcfp.pdf -> fluentReports
Many thanks ...
I believe (after looking on logs) EJSON.clone just go crazy in the infinity loop.
I recommend to stick with Fibers/Future library when implementing synchronous methods (i've simplified you code, but you should get the idea):
import Future from 'fibers/future';
Meteor.methods({
'requerimientos.reports.general_4'() {
const fut = new Future;
FluentReports.addFile(finalPath, { fileName: fileName, type: 'pdf', fileId: new Mongo.ObjectID()._str, meta: {owner: this.userId, createdAt: new Date()} }, );
return fut.wait();
}
});
Or even simpler with Meteor's wrapAsync:
const addFileSync = Meteor.wrapAsync(FluentReports.addFile, addFileSync);
Meteor.methods({
'requerimientos.reports.general_4'() {
return addFileSync(finalPath, { fileName: fileName, type: 'pdf', fileId: new Mongo.ObjectID()._str, meta: {owner: this.userId, createdAt: new Date()} });
}
});
Hi @dr-dimitru,
many thanks for your recomendation. I ended up using _Meteor.wrapAsync_ and _addFile_ worked fine.
Now, another issue arose when I added some code to return a _download link_ to the client. So, this is my method, with added code to create and return the link:
var addFileSync = Meteor.wrapAsync(FluentReports.addFile, FluentReports);
try {
result = addFileSync(finalPath, { fileName: fileName,
type: 'pdf',
fileId: new Mongo.ObjectID()._str,
meta: {owner: this.userId, createdAt: new Date()}
});
report = FluentReports.findOne({ _id: result._id });
} catch(error) {
return {
error: true,
message: `Error: ha ocurrido un error: ${error.message}`,
}
}
return {
error: false,
link: `<a href="${report.link()}" target="_blank">Get report ...</a>`,
}
However, when the method returns to the client and I click that link, I get the dreaded error:
Failed to load pdf document.
If a go to the file and do a double-click, it opens fine in the pdf reader.
Of course, I must be doing something wrong, but what could it be?
If you consider it better, I can open a different issue for this one.
Many thanks for your all your efforts, and bye ...
@mgrivera I recommend to take a look on this example
@mgrivera this documentation should help as well
Hi @dr-dimitru , everything is working fine right now. Many thanks for all your help.
The final (condensed) code follows:
'requerimientos.reports.general'() {
... ...
var addFileSync = Meteor.wrapAsync(FluentReports.addFile, FluentReports);
let result;
try {
result = addFileSync(finalPath, { fileName: fileName,
type: 'pdf',
fileId: new Mongo.ObjectID()._str,
meta: {owner: this.userId, createdAt: new Date()}
});
} catch(error) {
return {
error: true,
message: `Error: some error has ocurrend: ${error.message}`,
}
}
return {
error: false,
result: result
}
}
const getReportGeneral2 = () => {
Meteor.call('requerimientos.reports.general', (error, result) => {
if (error || result.error) {
// report your error
return;
}
Meteor.subscribe('meteor.files.by.id', result.result._id, () => {
const report = FluentReports.findOne(result.result._id);
if (!report) {
// report your error ...
} else {
const link = ` <a href="${report.link()}?download=true" download="${report.name}" target="_blank">${report.name}$</a> `;
// show link so user can download the file
}
});
});
}
import { Meteor } from 'meteor/meteor';
import { FluentReports } from '/imports/api/collections/meteor_files/fluentReports';
Meteor.publish("meteor.files.by.id", function (fileId) {
return FluentReports.collection.find({ _id: fileId });
})
Many thanks again. I'm just beginning to know the library; however I can sense its very well done. And very useful.
@mgrivera I'm glad this was quickly solved
Please, support this project by:
Feel free to close it in case if the issue is solved on your end.
Most helpful comment
Hi @dr-dimitru , everything is working fine right now. Many thanks for all your help.
The final (condensed) code follows:
1) This is how I coded the meteor method:
2) This is how I call the method from client:
3) This is the needed subscription:
Many thanks again. I'm just beginning to know the library; however I can sense its very well done. And very useful.