~michihenning/storage-framework/check-server-side-metadata

« back to all changes in this revision

Viewing changes to src/provider/internal/Handler.cpp

  • Committer: Tarmac
  • Author(s): Michi Henning
  • Date: 2016-08-11 04:20:23 UTC
  • mfrom: (10.11.10 exception-marshaling)
  • Revision ID: tarmac-20160811042023-dyu0x0rz3yrnr8md
Added exception hierarchy for server side, plus marshaling/unmarshaling code
for exceptions. Some coverage in the remote client to show that this works
(but more coverage is needed).

Approved by James Henstridge, unity-api-1-bot.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 */
18
18
 
19
19
#include <unity/storage/provider/internal/Handler.h>
 
20
 
 
21
#include <unity/storage/internal/dbus_error.h>
20
22
#include <unity/storage/provider/internal/AccountData.h>
 
23
#include <unity/storage/provider/internal/dbusmarshal.h>
21
24
#include <unity/storage/provider/internal/DBusPeerCache.h>
22
25
#include <unity/storage/provider/internal/MainLoopExecutor.h>
23
26
#include <unity/storage/provider/ProviderBase.h>
 
27
#include <unity/storage/provider/Exceptions.h>
24
28
 
25
29
#include <stdexcept>
26
30
 
 
31
using namespace unity::storage::internal;
27
32
using namespace std;
28
33
 
29
 
namespace
30
 
{
31
 
char const ERROR[] = "com.canonical.StorageFramework.Provider.Error";
32
 
}
33
 
 
34
34
namespace unity
35
35
{
36
36
namespace storage
53
53
    auto peer_future = account_->dbus_peer().get(message_.service());
54
54
    creds_future_ = peer_future.then(
55
55
        EXEC_IN_MAIN
56
 
        [this](decltype(peer_future) f) {
 
56
        [this](decltype(peer_future) f)
 
57
        {
57
58
            auto info = f.get();
58
59
            if (info.valid)
59
60
            {
64
65
            }
65
66
            else
66
67
            {
67
 
                reply_ = message_.createErrorReply(
68
 
                    ERROR, "Handler::begin(): could not retrieve credentials");
 
68
                auto ep = make_exception_ptr(PermissionException("Handler::begin(): could not retrieve credentials"));
 
69
                marshal_exception(ep);
69
70
                QMetaObject::invokeMethod(this, "send_reply",
70
71
                                          Qt::QueuedConnection);
71
72
            }
75
76
void Handler::credentials_received()
76
77
{
77
78
    boost::future<QDBusMessage> msg_future;
78
 
    try {
 
79
    try
 
80
    {
79
81
        msg_future = callback_(account_, context_, message_);
80
 
    } catch (std::exception const& e) {
81
 
        reply_ = message_.createErrorReply(ERROR, e.what());
 
82
    }
 
83
    catch (std::exception const& e)
 
84
    {
 
85
        marshal_exception(current_exception());
82
86
        QMetaObject::invokeMethod(this, "send_reply", Qt::QueuedConnection);
83
87
        return;
84
88
    }
85
89
    reply_future_ = msg_future.then(
86
90
        EXEC_IN_MAIN
87
 
        [this](decltype(msg_future) f) {
 
91
        [this](decltype(msg_future) f)
 
92
        {
88
93
            try
89
94
            {
90
95
                reply_ = f.get();
91
96
            }
92
 
            catch (std::exception const& e)
 
97
            catch (std::exception const&)
93
98
            {
94
 
                reply_ = message_.createErrorReply(ERROR, e.what());
 
99
                marshal_exception(current_exception());
95
100
            }
96
101
            QMetaObject::invokeMethod(this, "send_reply", Qt::QueuedConnection);
97
102
        });
103
108
    Q_EMIT finished();
104
109
}
105
110
 
 
111
void Handler::marshal_exception(exception_ptr ep)
 
112
{
 
113
    try
 
114
    {
 
115
        rethrow_exception(ep);
 
116
    }
 
117
    catch (StorageException const& e)
 
118
    {
 
119
        reply_ = message_.createErrorReply(QString(DBUS_ERROR_PREFIX) + QString::fromStdString(e.type()),
 
120
                                           QString::fromStdString(e.error_message()));
 
121
        try
 
122
        {
 
123
            throw;
 
124
        }
 
125
        catch (NotExistsException const& e)
 
126
        {
 
127
            reply_ << QVariant(QString::fromStdString(e.key()));
 
128
        }
 
129
        catch (ExistsException const& e)
 
130
        {
 
131
            reply_ << QVariant(QString::fromStdString(e.native_identity()));
 
132
            reply_ << QVariant(QString::fromStdString(e.name()));
 
133
        }
 
134
        catch (ResourceException const& e)
 
135
        {
 
136
            reply_ << QVariant(e.error_code());
 
137
        }
 
138
        catch (StorageException const&)
 
139
        {
 
140
            // Some other sub-type of StorageException without additional data members.
 
141
        }
 
142
    }
 
143
    catch (std::exception const& e)
 
144
    {
 
145
        reply_ = message_.createErrorReply(QString(DBUS_ERROR_PREFIX) + "UnknownException", e.what());
 
146
    }
 
147
    catch (...)
 
148
    {
 
149
        reply_ = message_.createErrorReply(QString(DBUS_ERROR_PREFIX) + "UnknownException", "unknown exception type");
 
150
    }
 
151
}
 
152
 
106
153
}
107
154
}
108
155
}