1

我有一个具有多个功能的 api 调用。除了对每个方法都应用错误处理之外,是否可以使用将错误发送给 UI 开发人员的全局错误处理代码。

代码如下:

app.post('/billing/pricingdetails', function (req, res) {
    console.log('pricing api called');
    var workload = req.body;
    var resourcelevelPricing = {};
    var response = {};
    var workloadinfo = {
        workloadId: workload.workloadId,
        ownerId: workload.ownerId,
        uniqueName: workload.uniqueName,
        name: workload.name
    }
    var pricing = {}
    var allresourceIdentifiers;

    if (workload.elements && workload.elements.length > 0) {
        var elementlevelpricingSummary = {};
        var elementArray = [];
        var allresourceIdentifierArray = [];
        var elementinfo = {};
        var metadataModified = {};
        var elementsParam = workload.elements;
        // handle configurable resource
        var configurableElementarray = [];

        // create array of all the elements in workloadjson - to be used for resourcelevel (instance/image), charamountunitlevel, resourcetypelevel pricing detail
        for (var index in elementsParam) {
            // if condition skips the uri of configurable resources - handle configurable resource
            if(!elementsParam[index].parameters.ResourceParameters) 
            {
                allresourceIdentifierArray.push(elementsParam[index].uri);

                if (elementsParam[index].parameters.imageUri) {
                allresourceIdentifierArray.push(elementsParam[index].parameters.imageUri);
                }
            }
        }

        var allresourceIdentifiers = allresourceIdentifierArray.join(',');

        // call the functionalities that gives the each level of pricing detail synchronously to construct the workload json 
        async.series([
        function (callback) {

            getpricingSummary(elementsParam, function (err, workloadinfo) {
                if(err){

                }
                else
                {
                callback(null, workloadinfo);
                }

            });
        },
        function (callback) {

            getPricingforResourceIdentifiers(allresourceIdentifiers, function (err, pricingDetail) {

                pricing.resourceLevel = pricingDetail;
                callback(null, pricingDetail);

            });
        },
        function (callback) {

            getchargeamountunitlevelPricing(allresourceIdentifiers, function (err, pricingDetail) {

                //merge configurable resource with concrete resource pricing details - handle configurable resource
                if(configurableElementarray.length > 0)
                {

                    var concatednatedArray = pricingDetail.concat(configurableElementarray);

                    var finalResult = [];

                    var i = concatednatedArray.reduce(function (result, o) {

                    var key  = o.chargeAmountUnit + o.currencyCode;

                    if (!(key in result)) {
                    result.arr.push(result[key] = o);
                    finalResult.push(result);
                    } 

                    else {
                    result[key].chargeAmount += Number(o.chargeAmount);
                    }

                    return result;
                    }, { arr: [] }).arr;

                    pricing.chargeamountunitLevel = i;

                    trace.info(i);

                }
                else
                {
                    pricing.chargeamountunitLevel = pricingDetail;  
                }
                callback(null, pricingDetail);

            });
        },
        function (callback) {

            getresourcetypelevelPricing(allresourceIdentifiers, function (err, pricingDetail) {

                if(configurableElementarray.length > 0)
                {

                    var concatednatedArray = pricingDetail.concat(configurableElementarray);

                    var i = concatednatedArray.reduce(function (result, o) {

                    var key  = o.chargeAmountUnit + o.currencyCode + o.Name;

                    if (!(key in result)) {
                    result.arr.push(result[key] = o);
                    } 

                    else {
                    result[key].chargeAmount += o.chargeAmount;
                    }

                    return result;
                    }, { arr: [] }).arr;

                    pricing.resourcetypeLevel = i;
                    trace.info(i);

                }
                else
                {
                    pricing.resourcetypeLevel = pricingDetail;
                }
                callback(null, pricingDetail);

            });
        }
        ],
        function (err, result) {

            workloadinfo.pricing = pricing;
            res.send(workloadinfo);

        });

        // get element level pricing summary for each elements (vm/vs) in the array within workload json - the output to be appended within metadata of workload json
        function getpricingSummary(elementsParam, callback) {

            async.forEachSeries(elementsParam, createResponse, function (err,result) {

                return callback(null, result);

            });
        };

        // this method called by async.forEachSeries passing each elements (vm/vs) of workload
        function createResponse(elements, callback) {

            var resourceIdentifierArray = [];

            elementinfo = elements;

            resourceIdentifierArray.push(elements.uri);

            if (elements.parameters.imageUri) {

                resourceIdentifierArray.push(elements.parameters.imageUri);
            }

            // build string of resourceIdentifier (instance/image) for input element
            var resourceIdentifiers = resourceIdentifierArray.join(',');

            console.log(resourceIdentifiers);

            if(elements.parameters.ResourceParameters)
            {
                trace.info('1');

                trace.info(elements.parameters.ResourceParameters);

                var configJson = JSON.parse(elements.parameters.ResourceParameters);

                trace.info(Number(configJson.cpuCount));

                metadataModified = elements.metadata;

                // TODO : Remove this hard-coding
                elementlevelpricingSummary.Name = 'Hardware';

                if(configJson.totalUnitPrice)
                {
                    var chargeAmount = configJson.totalUnitPrice;

                    elementlevelpricingSummary.chargeAmount = Math.round(chargeAmount * 100)/100;
                }
                if(configJson.ChargeAmountUnit)
                {
                    var chargeAmountUnit = configJson.ChargeAmountUnit;

                    elementlevelpricingSummary.chargeAmountUnit = configJson.ChargeAmountUnit;
                }
                if(configJson.CurrencyCode)
                {
                    var currencyCode = configJson.CurrencyCode;

                    elementlevelpricingSummary.currencyCode = configJson.CurrencyCode;
                }   

                metadataModified.pricingSummary = elementlevelpricingSummary;

                configurableElementarray.push(elementlevelpricingSummary);

                // delete original metadata from workload json (to be replaced by metadata containing pricing summary)
                delete elementinfo.metadata;

                elementinfo.metadata = metadataModified;

                elementArray.push(elementinfo);

                // global workloadinfo variable is appended with array of elements with its pricing summary within metadata of respective elements
                workloadinfo.elements = elementArray;

                return callback();
            }

            else
            {
                // Get element level pricing summary
                mysql.elementlevelpricing(resourceIdentifiers, conn, function (result) {

                elementlevelpricingSummary = result;

                metadataModified = elements.metadata;

                metadataModified.pricingSummary = elementlevelpricingSummary;

                // delete original metadata from workload json (to be replaced by metadata containing pricing summary)
                delete elementinfo.metadata;

                elementinfo.metadata = metadataModified;

                elementArray.push(elementinfo);

                // global workloadinfo variable is appended with array of elements with its pricing summary within metadata of respective elements
                workloadinfo.elements = elementArray;

                return callback(null,workloadinfo);

                });
            }
        };

        function getPricingforResourceIdentifiers(resourceIdentifiers, callback) {

            mysql.pricingDetail(resourceIdentifiers, conn, function (result) {

                return callback(null, result);

            });
        };

        function getchargeamountunitlevelPricing(resourceIdentifiers, callback) {

            mysql.chargeamountunitlevelPricing(resourceIdentifiers, conn, function (result) {

                return callback(null, result);

            });
        };

        function getresourcetypelevelPricing(resourceIdentifiers, callback) {

            mysql.resourcetypelevelPricing(resourceIdentifiers, conn, function (result) {

                return callback(null, result);

            });
        };

    };

});
4

1 回答 1

1

使用 Express,您可以安装一个错误处理程序,当您的任何路由中发生错误时将调用该错误处理程序:

// somewhere at the end of your middleware/route chain
app.use(function(err, req, res, next) {
  res.send(500, err.message); // or whatever you want to send back
});

最好还是重新抛出代码中出现的任何错误:

if (err) throw err;

此外,由于您使用的是async,因此您始终可以将错误传播回它:

if (err) return callback(err);

并在最终回调中处理错误。

于 2013-10-13T11:56:38.530 回答