diff --git a/core/Segment.php b/core/Segment.php
index 01e056bf68f4c823a5caada04f9372c354092bd0..e12b165028c1290bb0679243119f23cb5ade9d42 100644
--- a/core/Segment.php
+++ b/core/Segment.php
@@ -451,4 +451,14 @@ class Segment
         $query = $this->buildSelectQuery($select, $from, $where, $orderBy, $groupBy);
         return $query;
     }
-}
+
+    /**
+     * Returns the segment string.
+     *
+     * @return string
+     */
+    public function __toString()
+    {
+        return (string) $this->getString();
+    }
+}
\ No newline at end of file
diff --git a/plugins/CoreHome/angularjs/common/services/piwik-api.js b/plugins/CoreHome/angularjs/common/services/piwik-api.js
index 62625642488c0817c85a55e31590e8dd3e16be2a..d92bf0436c3bff20cb75dab3150b4cf007f2f117 100644
--- a/plugins/CoreHome/angularjs/common/services/piwik-api.js
+++ b/plugins/CoreHome/angularjs/common/services/piwik-api.js
@@ -37,11 +37,33 @@ angular.module('piwikApp.service').factory('piwikApi', function ($http, $q, $roo
         postParams = {};
     }
 
+    function isErrorResponse(response) {
+        return response && response.result == 'error';
+    }
+
+    function createResponseErrorNotification(response, options) {
+        if (response.message) {
+            var UI = require('piwik/UI');
+            var notification = new UI.Notification();
+            notification.show(response.message, {
+                context: 'error',
+                type: 'toast',
+                id: 'ajaxHelper',
+                placeat: options.placeat
+            });
+            notification.scrollToNotification();
+        }
+    }
+
     /**
      * Send the request
      * @return $promise
      */
-    function send () {
+    function send (options) {
+        if (!options) {
+            options = {};
+        }
+
         var deferred = $q.defer(),
             requestPromise = deferred.promise;
 
@@ -50,21 +72,10 @@ angular.module('piwikApp.service').factory('piwikApi', function ($http, $q, $roo
         };
 
         var onSuccess = function (response) {
-            if (response && response.result == 'error') {
-                if (response.message) {
-                    onError(response.message);
-
-                    var UI = require('piwik/UI');
-                    var notification = new UI.Notification();
-                    notification.show(response.message, {
-                        context: 'error',
-                        type: 'toast',
-                        id: 'ajaxHelper'
-                    });
-                    notification.scrollToNotification();
-                } else {
-                    onError(null);
-                }
+            if (isErrorResponse(response)) {
+                onError(response.message || null);
+
+                createResponseErrorNotification(response, options);
             } else {
                 deferred.resolve(response);
             }
@@ -189,26 +200,26 @@ angular.module('piwikApp.service').factory('piwikApi', function ($http, $q, $roo
      * Perform a reading API request.
      * @param getParams
      */
-    piwikApi.fetch = function (getParams) {
+    piwikApi.fetch = function (getParams, options) {
 
         getParams.module = getParams.module || 'API';
         getParams.format = 'JSON2';
 
         addParams(getParams, 'GET');
 
-        var promise = send();
+        var promise = send(options);
 
         reset();
 
         return promise;
     };
 
-    piwikApi.post = function (getParams, _postParams_) {
+    piwikApi.post = function (getParams, _postParams_, options) {
         if (_postParams_) {
             postParams = _postParams_;
         }
 
-        return this.fetch(getParams);
+        return this.fetch(getParams, options);
     };
 
     /**
@@ -216,22 +227,41 @@ angular.module('piwikApp.service').factory('piwikApi', function ($http, $q, $roo
      * Bulk requests allow you to execute multiple Piwik requests with one HTTP request.
      *
      * @param {object[]} requests
+     * @param {object} options
      * @return {HttpPromise} a promise that is resolved when the request finishes. The argument passed
      *                       to the .then(...) callback will be an array with one element per request
      *                       made.
      */
-    piwikApi.bulkFetch = function (requests) {
+    piwikApi.bulkFetch = function (requests, options) {
         var bulkApiRequestParams = {
             urls: requests.map(function (requestObj) { return '?' + $.param(requestObj); })
         };
 
-        return this.post({method: "API.getBulkRequest"}, bulkApiRequestParams).then(function (response) {
-            if (!(response instanceof Array)) {
-                response = [response];
-            }
+        var deferred = $q.defer(),
+            requestPromise = this.post({method: "API.getBulkRequest"}, bulkApiRequestParams, options).then(function (response) {
+                if (!(response instanceof Array)) {
+                    response = [response];
+                }
 
-            return response;
-        });
+                // check for errors
+                for (var i = 0; i != response.length; ++i) {
+                    var specificResponse = response[i];
+
+                    if (isErrorResponse(specificResponse)) {
+                        deferred.reject(specificResponse.message || null);
+
+                        createResponseErrorNotification(specificResponse, options || {});
+
+                        return;
+                    }
+                }
+
+                deferred.resolve(response);
+            }).catch(function () {
+                deferred.reject.apply(deferred, arguments);
+            });
+
+        return deferred.promise;
     };
 
     return piwikApi;
diff --git a/plugins/CoreHome/angularjs/common/services/piwik-api_spec.js b/plugins/CoreHome/angularjs/common/services/piwik-api_spec.js
index 803cfa30e7a5e1cdd3246046e6d50a53dda2a6d8..6e49c14ed1e06dfc71e574dc7d9533a2642c4a4d 100644
--- a/plugins/CoreHome/angularjs/common/services/piwik-api_spec.js
+++ b/plugins/CoreHome/angularjs/common/services/piwik-api_spec.js
@@ -9,8 +9,14 @@ describe('piwikApiClient', function () {
     var piwikApi,
         $httpBackend;
 
-    function extendHttpBackendMock($httpBackend) {
-        return $httpBackend;
+    if (!window.piwik) window.piwik = {};
+    if (!window.piwik.UI) window.piwik.UI = {};
+    if (!window.piwik.UI.Notification) {
+        window.piwik.UI.Notification = function () {
+            this.show = function () {};
+            this.scrollToNotification = function () {};
+            return this;
+        };
     }
 
     beforeEach(module('piwikApp.service'));
@@ -19,6 +25,15 @@ describe('piwikApiClient', function () {
 
         $httpBackend = $injector.get('$httpBackend');
 
+        $httpBackend.when('POST', /.*getBulkRequest.*/, /.*errorAction.*/).respond(function (method, url, data, headers) {
+            url = url.replace(/date=[^&]+/, "date=");
+
+            var errorResponse = {result: 'error', message: "error message"},
+                successResponse= "Response #2: " + url + " - " + data;
+
+            return [200, [errorResponse, successResponse]];
+        });
+
         $httpBackend.when('POST', /.*getBulkRequest.*/).respond(function (method, url, data, headers) {
             url = url.replace(/date=[^&]+/, "date=");
 
@@ -222,4 +237,42 @@ describe('piwikApiClient', function () {
 
         $httpBackend.flush();
     });
+
+    it("should correctly handle errors in a bulk request response", function (done) {
+        piwikApi.bulkFetch([
+            {
+                method: "SomePlugin.errorAction"
+            },
+            {
+                method: "SomeOtherPlugin.whatever"
+            }
+        ]).then(function (response) {
+            done(new Error("promise resolved after bulkFetch request returned an error (response = " + JSON.stringify(response) + ")"));
+        }).catch(function (error) {
+            expect(error).to.equal("error message");
+
+            done();
+        });
+
+        $httpBackend.flush();
+    });
+
+    it("shuld correctly handle errors in a bulk request response, regardless of error location", function (done) {
+        piwikApi.bulkFetch([
+            {
+                method: "SomeOtherPlugin.whatever"
+            },
+            {
+                method: "SomePlugin.errorAction"
+            }
+        ]).then(function (response) {
+            done(new Error("promise resolved after bulkFetch request returned an error (response = " + JSON.stringify(response) + ")"));
+        }).catch(function (error) {
+            expect(error).to.equal("error message");
+
+            done();
+        });
+
+        $httpBackend.flush();
+    });
 });
\ No newline at end of file
diff --git a/plugins/CoreHome/angularjs/dialogtoggler/dialogtoggler-urllistener-service.js b/plugins/CoreHome/angularjs/dialogtoggler/dialogtoggler-urllistener-service.js
index c1f07e2b829856a3dee594bfaa680c7590a3980c..dc8be42323a67e8f697636d8aa3ea1b88c995351 100644
--- a/plugins/CoreHome/angularjs/dialogtoggler/dialogtoggler-urllistener-service.js
+++ b/plugins/CoreHome/angularjs/dialogtoggler/dialogtoggler-urllistener-service.js
@@ -52,13 +52,11 @@ angular.module('piwikApp').factory('piwikDialogtogglerUrllistener', function ($r
 
     service.checkUrlForDialog = function () {
         var dialogParamValue = $location.search()[dialogQueryParamName];
-        if (dialogParamValue
-            && directiveExists(dialogParamValue)
-        ) {
+        if (dialogParamValue && directiveExists(dialogParamValue)) {
             var dialog = ngDialog.open({
                 template: getHtmlFromDialogQueryParam(dialogParamValue),
                 plain: true,
-                className: ''//'ngdialog-theme-default'
+                className: ''
             });
 
             dialog.closePromise.then(function () {