diff --git a/lib/private/connector/sabre/auth.php b/lib/private/connector/sabre/auth.php
index 5a32a9112ba2a4ee0ed90a705d44c614d32fb8bc..8a6eaab5bf81191f96337f7adcadbd49cb96fdfb 100644
--- a/lib/private/connector/sabre/auth.php
+++ b/lib/private/connector/sabre/auth.php
@@ -30,7 +30,12 @@
  */
 namespace OC\Connector\Sabre;
 
-class Auth extends \Sabre\DAV\Auth\Backend\AbstractBasic {
+use Exception;
+use Sabre\DAV\Auth\Backend\AbstractBasic;
+use Sabre\DAV\Exception\NotAuthenticated;
+use Sabre\DAV\Exception\ServiceUnavailable;
+
+class Auth extends AbstractBasic {
 	const DAV_AUTHENTICATED = 'AUTHENTICATED_TO_DAV_BACKEND';
 
 	/**
@@ -69,7 +74,7 @@ class Auth extends \Sabre\DAV\Auth\Backend\AbstractBasic {
 		} else {
 			\OC_Util::setUpFS(); //login hooks may need early access to the filesystem
 			if(\OC_User::login($username, $password)) {
-			        // make sure we use owncloud's internal username here
+			        // make sure we use ownCloud's internal username here
 			        // and not the HTTP auth supplied one, see issue #14048
 			        $ocUser = \OC_User::getUser();
 				\OC_Util::setUpFS($ocUser);
@@ -99,21 +104,30 @@ class Auth extends \Sabre\DAV\Auth\Backend\AbstractBasic {
 	}
 
 	/**
-	  * Override function here. We want to cache authentication cookies
-	  * in the syncing client to avoid HTTP-401 roundtrips.
-	  * If the sync client supplies the cookies, then OC_User::isLoggedIn()
-	  * will return true and we can see this WebDAV request as already authenticated,
-	  * even if there are no HTTP Basic Auth headers.
-	  * In other case, just fallback to the parent implementation.
-	  *
-	  * @param \Sabre\DAV\Server $server
-	  * @param $realm
-	  * @return bool
-	  */
+	 * Override function here. We want to cache authentication cookies
+	 * in the syncing client to avoid HTTP-401 roundtrips.
+	 * If the sync client supplies the cookies, then OC_User::isLoggedIn()
+	 * will return true and we can see this WebDAV request as already authenticated,
+	 * even if there are no HTTP Basic Auth headers.
+	 * In other case, just fallback to the parent implementation.
+	 *
+	 * @param \Sabre\DAV\Server $server
+	 * @param string $realm
+	 * @return bool
+	 * @throws ServiceUnavailable
+	 */
 	public function authenticate(\Sabre\DAV\Server $server, $realm) {
 
-		$result = $this->auth($server, $realm);
-		return $result;
+		try {
+			$result = $this->auth($server, $realm);
+			return $result;
+		} catch (NotAuthenticated $e) {
+			throw $e;
+		} catch (Exception $e) {
+			$class = get_class($e);
+			$msg = $e->getMessage();
+			throw new ServiceUnavailable("$class: $msg");
+		}
     }
 
 	/**
diff --git a/remote.php b/remote.php
index c1077e42672092506eb0f997a118ccd6ac5d0eb3..0b43f949ad48bf9db85d407907162035eedae956 100644
--- a/remote.php
+++ b/remote.php
@@ -25,22 +25,72 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>
  *
  */
+
+use OC\Connector\Sabre\ExceptionLoggerPlugin;
+use Sabre\DAV\Exception\ServiceUnavailable;
+use Sabre\DAV\Server;
+
+/**
+ * Class RemoteException
+ * Dummy exception class to be use locally to identify certain conditions
+ */
+class RemoteException extends Exception {
+}
+
+/**
+ * @param Exception $e
+ */
+function handleException(Exception $e) {
+	$request = \OC::$server->getRequest();
+	// in case the request content type is text/xml - we assume it's a WebDAV request
+	$isXmlContentType = strpos($request->getHeader('Content-Type'), 'text/xml');
+	if ($isXmlContentType === 0) {
+		// fire up a simple server to properly process the exception
+		$server = new Server();
+		$server->addPlugin(new ExceptionLoggerPlugin('webdav', \OC::$server->getLogger()));
+		$server->on('beforeMethod', function () use ($e) {
+			if ($e instanceof RemoteException) {
+				switch ($e->getCode()) {
+					case OC_Response::STATUS_SERVICE_UNAVAILABLE:
+						throw new ServiceUnavailable($e->getMessage());
+					case OC_Response::STATUS_NOT_FOUND:
+						throw new \Sabre\DAV\Exception\NotFound($e->getMessage());
+				}
+			}
+			$class = get_class($e);
+			$msg = $e->getMessage();
+			throw new ServiceUnavailable("$class: $msg");
+		});
+		$server->exec();
+	} else {
+		$statusCode = OC_Response::STATUS_INTERNAL_SERVER_ERROR;
+		if ($e instanceof \OC\ServiceUnavailableException ) {
+			$statusCode = OC_Response::STATUS_SERVICE_UNAVAILABLE;
+		}
+		\OCP\Util::writeLog('remote', $e->getMessage(), \OCP\Util::FATAL);
+		if ($e instanceof RemoteException) {
+			OC_Response::setStatus($e->getCode());
+			OC_Template::printErrorPage($e->getMessage());
+		} else {
+			OC_Response::setStatus($statusCode);
+			OC_Template::printExceptionErrorPage($e);
+		}
+	}
+}
+
 try {
 	require_once 'lib/base.php';
 
 	if (\OCP\Util::needUpgrade()) {
 		// since the behavior of apps or remotes are unpredictable during
 		// an upgrade, return a 503 directly
-		OC_Response::setStatus(OC_Response::STATUS_SERVICE_UNAVAILABLE);
-		OC_Template::printErrorPage('Service unavailable');
-		exit;
+		throw new RemoteException('Service unavailable', OC_Response::STATUS_SERVICE_UNAVAILABLE);
 	}
 
 	$request = \OC::$server->getRequest();
 	$pathInfo = $request->getPathInfo();
 	if ($pathInfo === false || $pathInfo === '') {
-		OC_Response::setStatus(OC_Response::STATUS_NOT_FOUND);
-		exit;
+		throw new RemoteException('Path not found', OC_Response::STATUS_NOT_FOUND);
 	}
 	if (!$pos = strpos($pathInfo, '/', 1)) {
 		$pos = strlen($pathInfo);
@@ -50,8 +100,7 @@ try {
 	$file = \OC::$server->getConfig()->getAppValue('core', 'remote_' . $service);
 
 	if(is_null($file)) {
-		OC_Response::setStatus(OC_Response::STATUS_NOT_FOUND);
-		exit;
+		throw new RemoteException('Path not found', OC_Response::STATUS_NOT_FOUND);
 	}
 
 	// force language as given in the http request
@@ -82,12 +131,6 @@ try {
 	$baseuri = OC::$WEBROOT . '/remote.php/'.$service.'/';
 	require_once $file;
 
-} catch (\OC\ServiceUnavailableException $ex) {
-	OC_Response::setStatus(OC_Response::STATUS_SERVICE_UNAVAILABLE);
-	\OCP\Util::writeLog('remote', $ex->getMessage(), \OCP\Util::FATAL);
-	OC_Template::printExceptionErrorPage($ex);
 } catch (Exception $ex) {
-	OC_Response::setStatus(OC_Response::STATUS_INTERNAL_SERVER_ERROR);
-	\OCP\Util::writeLog('remote', $ex->getMessage(), \OCP\Util::FATAL);
-	OC_Template::printExceptionErrorPage($ex);
+	handleException($ex);
 }