0

I have the following scenario;

  1. User requests files to be attached to a project
  2. Ctrl first looks to see that the user has access to the project
  3. If user has access, then allow the files to be uploaded and attached
  4. If something went wrong with the upload then return the error that was found

Code

                projectService.getProject(ID)
                    .then(function (project) {
                        if (!project) {
                            return commonService.sendResponse(res, 404);
                        }                
                        fileService.handleFileUpload(ID, [].concat(req.files.file))
                            .then(function (files) {
                                return commonService.sendResponse(res, 200, assets);
                            });
                    })
                    .catch(function (err) {
                        return commonService.sendError(res, err);
                    })
                    .finally(function cleanup() {
                        console.log('Fileupload completed');
                    });

Note: happy path flow works however the handleFileUpload can return an error if certain conditions are not met. If this method returns an error the catch returns the correct error but in the logs I see the following:

[TypeError: Cannot call method 'then' of undefined]
    12:44:30.815 service [ERROR] Cannot call method 'then' of undefined (TypeError)

The line that it complains about is the following:

  .then(function (files) {

The handleFileUpload looks like the following:

 var handleFileUpload = function (projectId, fileList) {
    var deferred = Promise.defer();
    var reject = function (err) {
        deferred.reject(err);
    };

    if (!(containsThumb(fileList)){
        return reject(new Error('Missing thumbnail in request'));
    }

     /** some some logic **/
     return deferred.promise;
 };
}
exports.handleFileUpload = handleFileUpload;

Everything kinda works! But cant figure out the issue with the exception being logged.

Any help is appreciated.

J

user1859465
  • 883
  • 1
  • 11
  • 28

1 Answers1

1

You are missing a few returns in which case a function that is expected to return a promise does not do so:

projectService.getProject(ID)
    .then(function (project) {
        if (!project) {
            return commonService.sendResponse(res, 404);
        }                
        return fileService.handleFileUpload(ID, [].concat(req.files.file))
//      ^^^^^^ you will want to wait with `.catch` for this
            .then(function (files) {
                return commonService.sendResponse(res, 200, assets);
            });
    })
    .catch(function (err) {
        return commonService.sendError(res, err);
    })
    .finally(function cleanup() {
        console.log('Fileupload completed');
    });

var handleFileUpload = function (projectId, fileList) {
    var deferred = Promise.defer();
    var reject = function (err) {
        deferred.reject(err);
        return deferred.promise;
//      ^^^^^^
    };

    if (!(containsThumb(fileList)){
        return reject(new Error('Missing thumbnail in request'));
// this ^^^^^^ method must always return a promise
    }

     /** some some logic **/
     return deferred.promise;
 };
}

Oh, and make sure the second function does not use the deferred antipattern.

Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • I had been looking at it sooo much i didnt see it! Thanks soo much...had to add the catch as you mentioned. Is there anyway for that to be handled by the existing catch rather than introducting another one? Thanks again @bergi – user1859465 Feb 04 '15 at 14:33
  • I didn't mention any new catch to add? I said that you have to add the `return`, so that errors in the *returned* promise will be handled by the existing catch… – Bergi Feb 04 '15 at 15:08