diff --git a/meson.build b/meson.build
index 7e98eaae7dc513eb44946a97215a8b9ae940cf37..9019852727308e6bda5ea4a14d61420742267893 100644
--- a/meson.build
+++ b/meson.build
@@ -30,6 +30,7 @@ defines = ['-DBOOST_MPL_LIMIT_LIST_SIZE=30', '-DBOOST_MPL_CFG_NO_PREPROCESSED_HE
 moc_files = qt5.preprocess(moc_headers :
 	[
 		'src/client.h',
+		'src/debug_out.h',
 		'src/login.h',
 		'src/settings.h',
 		'src/sync.h',
@@ -41,6 +42,7 @@ moc_files = qt5.preprocess(moc_headers :
 sources = [
     'src/harbour-spoon.cpp',
     'src/client.cpp',
+    'src/debug_out.cpp',
     'src/login.cpp',
     'src/settings.cpp',
     'src/sync.cpp',
diff --git a/src/debug_out.cpp b/src/debug_out.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..95e51510c4e4d5ff42147c5f7f7e1afd97485ea5
--- /dev/null
+++ b/src/debug_out.cpp
@@ -0,0 +1,27 @@
+#include "debug_out.h"
+
+#include <sstream>
+
+#include <mtxclient/http/errors.hpp>
+
+QDebug operator<<(QDebug debug, const mtx::http::ClientError &error) {
+    QDebugStateSaver saver(debug);
+
+    auto s = [](const auto &a) {
+        std::stringstream s;
+        s << a;
+        return QString::fromStdString(s.str());
+    };
+
+    if (!error.parse_error.empty())
+        debug.nospace() << "JSON parse error: " << QString::fromStdString(error.parse_error);
+    if (error.status_code != boost::beast::http::status::ok)
+        debug.nospace() << "HTTP error: " << s(error.status_code);
+    if (error.error_code)
+        debug.nospace() << "Network error: " << s(error.error_code);
+    if (!error.matrix_error.error.empty())
+        debug.nospace() << "Matrix error " << QString::fromStdString(to_string(error.matrix_error.errcode)) << ": "
+                        << s(error.matrix_error.error);
+
+    return debug;
+}
diff --git a/src/debug_out.h b/src/debug_out.h
new file mode 100644
index 0000000000000000000000000000000000000000..c19cab6766809a236d7c1aa827c6ea14bf07bdeb
--- /dev/null
+++ b/src/debug_out.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include <QDebug>
+
+namespace mtx {
+namespace http {
+class ClientError;
+}
+} // namespace mtx
+
+QDebug operator<<(QDebug debug, const mtx::http::ClientError &);
diff --git a/src/harbour-spoon.cpp b/src/harbour-spoon.cpp
index fe31bb76cf6e26cb2b5bd3ea5695f0df34f11e3e..940d45eaa0af6aa4fd46f0420e8cabf8188212f6 100644
--- a/src/harbour-spoon.cpp
+++ b/src/harbour-spoon.cpp
@@ -10,6 +10,17 @@
 
 #include "models/roommodel.h"
 
+QDataStream &operator<<(QDataStream &out, const std::string &s) {
+    out << QString::fromStdString(s);
+    return out;
+}
+QDataStream &operator>>(QDataStream &in, std::string &s) {
+    QString qs;
+    in >> qs;
+    s = qs.toStdString();
+    return in;
+}
+
 int main(int argc, char *argv[]) {
     // SailfishApp::main() will display "qml/harbour-spoon.qml", if you need more
     // control over initialization, you can use:
@@ -26,6 +37,8 @@ int main(int argc, char *argv[]) {
     // Set up QML engine.
     qRegisterMetaType<Room>("Room");
     qRegisterMetaType<QSharedPointer<Room>>("QSharedPointer<Room>");
+    qRegisterMetaType<std::string>("std::string");
+    qRegisterMetaTypeStreamOperators<std::string>("std::string");
 
     QScopedPointer<QGuiApplication> app(SailfishApp::application(argc, argv));
     QScopedPointer<QQuickView> v(SailfishApp::createView());
diff --git a/src/login.cpp b/src/login.cpp
index 4e7a7fc9411e83a2e46ef658926c1138c04a224a..a561120cd83be022e08f92c41b2d019d6a86a212 100644
--- a/src/login.cpp
+++ b/src/login.cpp
@@ -18,6 +18,7 @@ void Login::tryReconnect() {
         http::client().set_port(s.server_port().value());
         http::client().set_device_id(s.device_id().value());
         http::client().set_access_token(s.access_token().value());
+
         emit loginSuccess();
     } catch (std::exception &e) {
         qWarning() << "Relogin failed: " << QString::fromStdString(e.what());
@@ -97,7 +98,7 @@ void Login::login(QString mxid, QString password, QString server) {
         homeserver = server.toStdString();
 
     http::client().login(user.localpart(), password.toStdString(),
-                         [this](const mtx::responses::Login &response, mtx::http::RequestErr error) {
+                         [this, homeserver](const mtx::responses::Login &response, mtx::http::RequestErr error) {
                              if (error) {
                                  qDebug() << "Failed login!\n";
                                  if (!error->matrix_error.error.empty()) {
@@ -125,7 +126,7 @@ void Login::login(QString mxid, QString password, QString server) {
                              s.access_token(response.access_token);
                              s.device_id(response.device_id);
                              s.user(response.user_id);
-                             s.server(response.home_server);
+                             s.server(homeserver);
                              s.server_port(http::client().port());
 
                              emit loginSuccess();
diff --git a/src/settings.cpp b/src/settings.cpp
index 338b23fd5756322cb955afce636f71127aa0c75d..f9db35ffbac61c2784d400734e3d1d3de588f8c3 100644
--- a/src/settings.cpp
+++ b/src/settings.cpp
@@ -10,7 +10,7 @@ using std::experimental::optional;
 Settings::Settings() {}
 
 void Settings::access_token(const std::string &access_token) {
-    settings.setValue(QString::fromStdString("access_token"), QString::fromStdString(access_token));
+    settings.setValue(QString::fromStdString("access_token"), QVariant::fromValue(access_token));
 }
 
 optional<std::string> Settings::access_token() {
@@ -22,7 +22,7 @@ optional<std::string> Settings::access_token() {
 }
 
 void Settings::device_id(const std::string &s) {
-    settings.setValue(QStringLiteral("device_id"), QString::fromStdString(s));
+    settings.setValue(QStringLiteral("device_id"), QVariant::fromValue(s));
 }
 
 optional<std::string> Settings::device_id() {
@@ -33,7 +33,7 @@ optional<std::string> Settings::device_id() {
     }
 }
 
-void Settings::server(const std::string &s) { settings.setValue(QStringLiteral("server"), QString::fromStdString(s)); }
+void Settings::server(const std::string &s) { settings.setValue(QStringLiteral("server"), QVariant::fromValue(s)); }
 
 optional<std::string> Settings::server() {
     if (settings.contains(QStringLiteral("server")))
@@ -44,7 +44,7 @@ optional<std::string> Settings::server() {
 }
 
 void Settings::user(const mtx::identifiers::User &s) {
-    settings.setValue(QStringLiteral("user"), QString::fromStdString(s.to_string()));
+    settings.setValue(QStringLiteral("user"), QVariant::fromValue(s.to_string()));
 }
 
 optional<mtx::identifiers::User> Settings::user() {
@@ -63,7 +63,7 @@ optional<mtx::identifiers::User> Settings::user() {
     }
 }
 
-void Settings::server_port(uint16_t s) { settings.setValue(QStringLiteral("server_port"), s); }
+void Settings::server_port(uint16_t s) { settings.setValue(QStringLiteral("server_port"), QVariant::fromValue(s)); }
 
 optional<uint16_t> Settings::server_port() {
     if (settings.contains(QStringLiteral("server_port")))
diff --git a/src/sync.cpp b/src/sync.cpp
index 967820fa135a8f72f2c6a9c4d6cad84ac5bc2948..ba0068a1e1afdfe70f955cc4725b9620e234ea2b 100644
--- a/src/sync.cpp
+++ b/src/sync.cpp
@@ -3,6 +3,7 @@
 #include <QtDebug>
 
 #include "client.h"
+#include "debug_out.h"
 
 void Sync::startSync() {
     qDebug() << "trying initial sync";
@@ -12,6 +13,7 @@ void Sync::startSync() {
     http::client().sync(opts, [this](const mtx::responses::Sync &res, mtx::http::RequestErr err) {
         if (err) {
             qDebug() << "Failed sync";
+            qDebug() << *err;
             return;
         }