2
votes

Is there a way to provide default error handler for all calls made with breeze?

Now I have to add .fail(onFail) for every promise returned by breeze.EntityManager.fetchEntityByKey / breeze.EntityQuery.execute / breeze.EntityManager.saveChanges

It would be best if I could set default error handler for all calls and override default handler for particular calls.

2
Your save fail logic should always have a different fail method IMHO but for the others if you are grouping them into generic calls agnostic of type all of your queries can go through the same calls, reducing both your query logic code and your fail logic - PW Kad
To elaborate on this a but further you could also use a base function to generate the query and then extend it where the fail logic is in there to only have it defined once. This may be easier for a newer breeze dev - PW Kad

2 Answers

2
votes

I started leaving a bunch of comments and decided to make it an answer instead. You can always do this to reduce the code needed and improve re-usability -

var thisQuery = breeze.entityQuery.from('Whatever').where('pwkad', '==', 'awesome');
queryRunner(thisQuery);

function queryRunner(query) {
    query.execute().fail(queryFailed);
};

function queryFailed(error) {
    console.log(error.message);
};

Which has a single defined queryFailed method shared when using the 'queryRunner'. Then you could put all of your reusable code that is agnostic of the type in there. To go a step further you could also build a base query that all other queries 'inherit' (I use that loosely) to where you use parameters to build out the queries and then only maintain a single code base. I highly recommend doing this (I use it in all of my Breeze.js production apps) as it forces you to follow conventions on both the front-end and API code. I won't give away my secret sauce of exactly how this looks for me but here is a quick example -

// All is pseudo code
function getEntityById (manager, type, resourcePath, forceRemote, idProp, idValue, params) {
    if (!manager) { throw "Must pass in a manager"; }

    var query = breeze.entityQuery.from(resourcePath).toType(type);

    if (!forceRemote) {
        // Put your code here to get from cache
        var entity = breeze.fetchEntityByKey();
        if (entity) {
            return entity;
        }
    }

    if (params) {
        // Pass in a valid params object and set it to whatever
        query.withParameters(params);
    }

    if (idValue && idProp) {
        query.where(idProp, '==', idValue);
    }

    query.execute().fail(queryFailed);

    function queryFailed(error) {
        console.log(error);
    }
}

Which could be called from anywhere that needs to 'get' an entity by Id -

var manager = new breeze.entityManager();

var hamburger = getEntityById(manager, 'Hamburger', 'Hamburgers', true, 'id', 1);

Using this method you can write one single breeze query and call it from anywhere saving tons of time and debugging provided you give the parameters correctly.

2
votes

breeze allows to set error handler on application startup:

var ajaxAdapter = breeze.config.getAdapterInstance("ajax");

ajaxAdapter.requestInterceptor = function (requestInfo) {
    // this method is called for every request made with breeze ajax adapter
    // all callbacks are in zConfig
    var
        successHandler = requestInfo.zConfig.success,
        errorHandler = requestInfo.zConfig.error || handleBadRequest,
        finalHandler = requestInfo.zConfig.finally; // final handler for calls, made directly with adapter

    if (finalHandler) {
        requestInfo.zConfig.success = function (response) {
            if(successHandler) {
                successHandler(response);
            }
            finalHandler(response);
        }
    }

    requestInfo.zConfig.error = function (response) {            
        switch (response.status) {
        case 400:
            // call error handler only for 'BadRequest'
            errorHandler(parseErrors(response));
            break;
        case 401:
            handleUnauthorizedRequest(response);
            break;
        default:
            handleServerOrUnrecognizedError(response);
            break;
        }
        if (finalHandler) {
            finalHandler(response);
        }
    };
};