简体   繁体   中英

Node.js promise with q not working as expected

this is my approach:

var q = require('q');
var request = require("request");

exports.route = function (req, res) {
    var userId = req.query.userId;

    if (!userId) {
        res.send(JSON.stringify({
            errorCode: 400,
            error: "userId is missing, please form your query like <url>/avatar?userId=00.42.1"
        }), 400);
        return;
    }
    getAvatar(userId).then(function (success) {
            console.log('success');
            res.json(success);
        }, function (error) {
            console.log('error');
            res.json({error: error});
        }
    );


};

function getAvatar(userId) {
    var isErrorInResponse = function (error, response) {
        return typeof error !== 'undefined' || error == null || response.statusCode > 202;
    };

    var deferred = q.defer();
    var url = "http://localhost/avatar" + userId;
    console.log(url);
    request(url, function (error, response, body) {
        if (isErrorInResponse(error, response)) {
            deferred.reject(new Error({error: error, response: response, body: body}));
        } else {
            deferred.resolve(body);
        }
    });
    return deferred.promise;
};

GET localhost:8090/avatar?userId=42 produces following log:

http://localhost/avatar/42
error

and sends this response to the client:

{
  "error": {}
}

And here is my versions, which I'm not able to update:

 "dependencies": {
    "consolidate": "0.9.0",
    "express": "3.1.0",
    "multipart-parser": "0.0.2",
    "mustache": "0.7.2",
    "poplib": "0.1.5",
    "q": "0.9.3",
    "q-io": "1.6.x",
    "request": "2.27.0",
    "string": "^2.2.0",
    "xml2js": "0.2.8"
  }

And the question is, why does the promise not receive the full error, I'm sending at deferred.reject(... and what have I to change so that it will work?

deferred.reject(new Error({error: error, response: response, body: body}));

The Error constructor takes in a string argument, not an object. Passing in anything other than a string will result in the argument being converted to a string, which for a plain object is [object Object] . Because an error object does not have any enumerable properties, JSON.stringify ing it results in {} . What you need is to pass in a string to the Error constructor and access the message property.

Reject:

deferred.reject(new Error(error));

Response:

getAvatar(userId).then(function (success) {
            console.log('success');
            res.json(success);
        }, function (error) {
            console.log('error');
            res.json({error: error.message});
        }
   );

If you want the error message to be an object, you'll have to stringify it. Alternatively, you can explicitly add those properties to the error object and they'll show up when the error is JSON .stringified, but this will also show up the stack property because Q adds it to support long stack traces.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM