Question

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.

Was it helpful?

Solution 2

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);
        }
    };
};

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top