Merge lp:~phablet-team/messaging-framework/catch-all-possible-exceptions into lp:messaging-framework

Proposed by Roberto Mier Escandon
Status: Merged
Approved by: Gustavo Pichorim Boiko
Approved revision: 45
Merged at revision: 44
Proposed branch: lp:~phablet-team/messaging-framework/catch-all-possible-exceptions
Merge into: lp:messaging-framework
Diff against target: 849 lines (+403/-170)
4 files modified
debian/changelog (+6/-0)
src/messaging/member.cpp (+2/-2)
src/messaging/qt/tp/connection.cpp (+169/-43)
src/messaging/qt/tp/text_channel.cpp (+226/-125)
To merge this branch: bzr merge lp:~phablet-team/messaging-framework/catch-all-possible-exceptions
Reviewer Review Type Date Requested Status
Gustavo Pichorim Boiko (community) Approve
system-apps-ci-bot continuous-integration Approve
PS Jenkins bot continuous-integration Pending
Review via email: mp+299907@code.launchpad.net

Commit message

Catched all plugin possible exceptions in messaging-fw

Description of the change

Catched all plugin possible exceptions in messaging-fw

To post a comment you must log in.
Revision history for this message
system-apps-ci-bot (system-apps-ci-bot) wrote :

PASSED: Continuous integration, rev:45
https://jenkins.canonical.com/system-apps/job/lp-messaging-framework-ci/17/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build/956
    SUCCESS: https://jenkins.canonical.com/system-apps/job/test-0-autopkgtest/label=phone-armhf,release=vivid+overlay,testname=default/171
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-0-fetch/956
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-1-sourcepkg/release=vivid+overlay/860
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-1-sourcepkg/release=xenial+overlay/860
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-1-sourcepkg/release=yakkety/860
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=vivid+overlay/857
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=vivid+overlay/857/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=xenial+overlay/857
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=xenial+overlay/857/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=yakkety/857
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=yakkety/857/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=vivid+overlay/857
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=vivid+overlay/857/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=xenial+overlay/857
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=xenial+overlay/857/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=yakkety/857
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=yakkety/857/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=vivid+overlay/857
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=vivid+overlay/857/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=xenial+overlay/857
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=xenial+overlay/857/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=yakkety/857
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=yakkety/857/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/system-apps/job/lp-messaging-framework-ci/17/rebuild

review: Approve (continuous-integration)
Revision history for this message
Gustavo Pichorim Boiko (boiko) wrote :

Looks good!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2016-07-08 13:55:33 +0000
3+++ debian/changelog 2016-07-13 04:54:46 +0000
4@@ -1,3 +1,9 @@
5+messaging-framework (0.1-1ubuntu20) vivid; urgency=medium
6+
7+ * Controlling any plugin exception to avoid fw crashing
8+
9+ -- Roberto Mier Escandon <roberto.escandon@canonical.com> Wed, 13 Jul 2016 12:48:54 +0800
10+
11 messaging-framework (0.1-1ubuntu19) vivid; urgency=medium
12
13 * Set group title on creation
14
15=== modified file 'src/messaging/member.cpp'
16--- src/messaging/member.cpp 2016-07-05 13:47:29 +0000
17+++ src/messaging/member.cpp 2016-07-13 04:54:46 +0000
18@@ -2,7 +2,7 @@
19
20 struct messaging::Member::Private
21 {
22- messaging::PendingStatus pending_list;
23+ messaging::PendingStatus pending_status;
24 };
25
26 messaging::Member::Member(std::string id,
27@@ -15,7 +15,7 @@
28
29 messaging::PendingStatus messaging::Member::pending_status() const
30 {
31- return impl->pending_list;
32+ return impl->pending_status;
33 }
34
35
36
37=== modified file 'src/messaging/qt/tp/connection.cpp'
38--- src/messaging/qt/tp/connection.cpp 2016-07-08 03:32:33 +0000
39+++ src/messaging/qt/tp/connection.cpp 2016-07-13 04:54:46 +0000
40@@ -193,14 +193,24 @@
41
42 // read the statuses supported by the plugin, and expose them to telepathy
43 Tp::SimpleStatusSpecMap statusMap;
44- auto statuses = connection->presence_manager()->get_valid_statuses();
45- for (auto it = statuses.begin(); it != statuses.end(); ++it)
46- {
47- statusMap.insert(QString::fromStdString(it->first),
48- Tp::SimpleStatusSpec{messaging_presence_type_to_telepathy(it->second.type),
49- (it->second.flags & StatusSpec::Flags::may_set_on_self) == StatusSpec::Flags::may_set_on_self,
50- (it->second.flags & StatusSpec::Flags::can_have_message) == StatusSpec::Flags::can_have_message});
51- }
52+
53+ try
54+ {
55+ auto statuses = connection->presence_manager()->get_valid_statuses();
56+ for (auto it = statuses.begin(); it != statuses.end(); ++it)
57+ {
58+ statusMap.insert(QString::fromStdString(it->first),
59+ Tp::SimpleStatusSpec{messaging_presence_type_to_telepathy(it->second.type),
60+ (it->second.flags & StatusSpec::Flags::may_set_on_self) == StatusSpec::Flags::may_set_on_self,
61+ (it->second.flags & StatusSpec::Flags::can_have_message) == StatusSpec::Flags::can_have_message});
62+ }
63+ }
64+ catch (...)
65+ {
66+ LOG(ERROR) << "PresenceManager::get_valid_statuses() implementation throws exception. Please review. " \
67+ "Providing empty valid statuses map to presence interface";
68+ }
69+
70
71 simplePresenceIface->setStatuses(statusMap);
72 plugInterface(Tp::AbstractConnectionInterfacePtr::dynamicCast(simplePresenceIface));
73@@ -215,15 +225,30 @@
74
75 mqt::tp::Connection::~Connection()
76 {
77- dbusConnection().unregisterObject(objectPath(), QDBusConnection::UnregisterTree);
78- dbusConnection().unregisterService(busName());
79+ try
80+ {
81+ dbusConnection().unregisterObject(objectPath(), QDBusConnection::UnregisterTree);
82+ dbusConnection().unregisterService(busName());
83+ }
84+ catch (...)
85+ {
86+ LOG(ERROR) << "An exception has been thrown when unregistering telepathy connection object and service";
87+ }
88 }
89
90 void mqt::tp::Connection::onDisconnected()
91 {
92 setStatus(Tp::ConnectionStatusDisconnected, Tp::ConnectionStatusReasonRequested);
93- connection->disconnect();
94- deleteLater();
95+
96+ try
97+ {
98+ connection->disconnect();
99+ deleteLater();
100+ }
101+ catch (...)
102+ {
103+ LOG(ERROR) << "An exception has been thrown when disconnecting framework connection implementation";
104+ }
105 }
106
107 void mqt::tp::Connection::on_message_without_chat_received(const Recipient::shared_ptr& recipient, const messaging::Message &message)
108@@ -233,8 +258,8 @@
109 return;
110 }
111
112- int handle = request_handles(Tp::HandleTypeContact, QStringList() << QString::fromStdString(recipient->id()), NULL)[0];
113 Tp::DBusError error;
114+ int handle = request_handles(Tp::HandleTypeContact, QStringList() << QString::fromStdString(recipient->id()), &error)[0];
115 QVariantMap request;
116 request[TP_QT_IFACE_CHANNEL + QLatin1String(".ChannelType")] = TP_QT_IFACE_CHANNEL_TYPE_TEXT;
117 request[TP_QT_IFACE_CHANNEL + QLatin1String(".TargetHandleType")] = Tp::HandleTypeContact;
118@@ -257,8 +282,17 @@
119 setStatus(static_cast<uint>(new_status), static_cast<uint>(reason));
120 Tp::SimpleContactPresences presences;
121 Tp::SimplePresence presence;
122+ PresenceManager::StatusMap statuses;
123
124- auto statuses = connection->presence_manager()->get_valid_statuses();
125+ try
126+ {
127+ statuses = connection->presence_manager()->get_valid_statuses();
128+ }
129+ catch (...)
130+ {
131+ LOG(ERROR) << "PresenceManager::get_valid_statuses() implementation throws exception. Please review it. " \
132+ "Providing empty valid statuses map to presence interface";
133+ }
134
135 if (static_cast<Tp::ConnectionStatus>(new_status) == Tp::ConnectionStatusConnected)
136 {
137@@ -295,13 +329,22 @@
138 return;
139 }
140
141- auto valid_statuses = connection->presence_manager()->get_valid_statuses();
142- if (valid_statuses.find(presence.status) == valid_statuses.end()) {
143- LOG(ERROR) << "trying to set presence to " << presence.status << " that is not a valid presence status";
144- return;
145+ try
146+ {
147+ auto valid_statuses = connection->presence_manager()->get_valid_statuses();
148+ if (valid_statuses.find(presence.status) == valid_statuses.end()) {
149+ LOG(ERROR) << "trying to set presence to " << presence.status << " that is not a valid presence status";
150+ return;
151+ }
152+ }
153+ catch (...)
154+ {
155+ LOG(ERROR) << "PresenceManager::get_valid_statuses() implementation throws exception. Please review it. " \
156+ "Providing empty valid statuses map to presence interface";
157 }
158
159- int handle = request_handles(Tp::HandleTypeContact, QStringList() << QString::fromStdString(recipient->id()), NULL)[0];
160+ Tp::DBusError error;
161+ int handle = request_handles(Tp::HandleTypeContact, QStringList() << QString::fromStdString(recipient->id()), &error)[0];
162 Tp::SimpleContactPresences presences;
163 Tp::SimplePresence tpPresence = Tp::SimplePresence{messaging_presence_type_to_telepathy(presence.type),
164 QString::fromStdString(presence.status),
165@@ -321,7 +364,16 @@
166
167 Tp::DBusError error;
168 int handle = request_handles(Tp::HandleTypeRoom, QStringList() << QString::fromStdString(new_group->id()), &error)[0];
169- QString initiator_normalized_id = QString::fromStdString(connection->normalize_identifier(initiator->id()));
170+
171+ QString initiator_normalized_id = QString::fromStdString(initiator->id());
172+ try
173+ {
174+ initiator_normalized_id = QString::fromStdString(connection->normalize_identifier(initiator->id()));
175+ }
176+ catch (...)
177+ {
178+ LOG(ERROR) << "An exception has been thrown when normalizing group initiator identifier. Using not normalized one";
179+ }
180 int initiator_handle = request_handles(Tp::HandleTypeContact, QStringList() << initiator_normalized_id, &error)[0];
181
182 // if there is an error requesting handles, reject the group creation
183@@ -337,6 +389,11 @@
184 LOG(ERROR) << "Group rejection failed, " << e.what();
185 error.set(TP_QT_ERROR_CANCELLED, "Group rejection failed");
186 }
187+ catch (...)
188+ {
189+ LOG(ERROR) << "Group rejection failed";
190+ error.set(TP_QT_ERROR_CANCELLED, "Group rejection failed");
191+ }
192 return;
193 }
194
195@@ -409,26 +466,55 @@
196 {
197 for (auto id : identifiers)
198 {
199- QString normalizedId = connection->normalize_identifier(id.toStdString()).c_str();
200+ QString normalizedId = id;
201+ try
202+ {
203+ normalizedId = connection->normalize_identifier(id.toStdString()).c_str();
204+ }
205+ catch (...)
206+ {
207+ LOG(ERROR) << "An exception has been thrown when normalizing identifier. Using not normalized one";
208+ return Tp::UIntList();
209+ }
210+
211+
212 if (handles_.right.count(normalizedId))
213 {
214 handles.append(handles_.right.at(normalizedId));
215 }
216 else
217 {
218- // before creating the handle, check that the id is valid
219- if (!connection->is_valid_identifier(normalizedId.toStdString())) {
220- if (error) {
221- error->set(TP_QT_ERROR_INVALID_HANDLE, "Identifier not valid.");
222+ try
223+ {
224+ // before creating the handle, check that the id is valid
225+ if (!connection->is_valid_identifier(normalizedId.toStdString())) {
226+ if (error) {
227+ error->set(TP_QT_ERROR_INVALID_HANDLE, "Identifier not valid.");
228+ }
229+ return Tp::UIntList();
230 }
231+ }
232+ catch (...)
233+ {
234+ LOG(ERROR) << "An exception has been thrown when evaluating messaging::Connection::is_valid_identifier() " \
235+ "for identifier: " << normalizedId.toStdString() << " ,please review its implementation";
236 return Tp::UIntList();
237 }
238
239 auto sample = ++counter;
240 handles_.insert(HandleIdPair(sample, normalizedId));
241 handles.append(sample);
242+
243 // request the presence status of the new handle
244- connection->presence_manager()->request_presence(recipient_from_identifier(normalizedId.toStdString()));
245+ try
246+ {
247+ connection->presence_manager()->request_presence(recipient_from_identifier(normalizedId.toStdString()));
248+ }
249+ catch (...)
250+ {
251+ LOG(ERROR) << "An exception has been thrown when requesting presence for " << normalizedId.toStdString();
252+ return Tp::UIntList();
253+ }
254 }
255 }
256 }
257@@ -475,7 +561,8 @@
258 if (request.contains(TP_QT_IFACE_CHANNEL + QLatin1String(".TargetID")))
259 {
260 QString identifier = request[TP_QT_IFACE_CHANNEL + QLatin1String(".TargetID")].toString();
261- final_handle = request_handles(target_handle_type, QStringList() << identifier, NULL)[0];
262+ Tp::DBusError error;
263+ final_handle = request_handles(target_handle_type, QStringList() << identifier, &error)[0];
264 }
265
266 return create_text_channel(target_handle_type, final_handle, request, error);
267@@ -498,10 +585,10 @@
268
269 if (target_handle_type == Tp::HandleTypeRoom)
270 {
271- std::shared_ptr<GroupStarter> group_starter = connection->group_starter();
272- messaging::Group::shared_ptr group = std::dynamic_pointer_cast<messaging::Group>(recipient);
273 try
274 {
275+ std::shared_ptr<GroupStarter> group_starter = connection->group_starter();
276+ messaging::Group::shared_ptr group = std::dynamic_pointer_cast<messaging::Group>(recipient);
277 group_manager = group_starter->accept_group(group);
278
279 // update recipient with id, title and members
280@@ -518,6 +605,12 @@
281 error->set(TP_QT_ERROR_CANCELLED, "Group creation rejected");
282 return Tp::BaseChannelPtr{};
283 }
284+ catch (...)
285+ {
286+ LOG(ERROR) << "Group creation rejected";
287+ error->set(TP_QT_ERROR_CANCELLED, "Group creation rejected");
288+ return Tp::BaseChannelPtr{};
289+ }
290 }
291 }
292 // channel is created from app
293@@ -533,10 +626,10 @@
294 recipient = std::make_shared<messaging::Group>(
295 group_handles_.left.find(target_handle)->second.toLatin1().data());
296
297- std::shared_ptr<GroupStarter> group_starter = connection->group_starter();
298- messaging::Group::shared_ptr group = std::dynamic_pointer_cast<messaging::Group>(recipient);
299 try
300 {
301+ std::shared_ptr<GroupStarter> group_starter = connection->group_starter();
302+ messaging::Group::shared_ptr group = std::dynamic_pointer_cast<messaging::Group>(recipient);
303 group_manager = group_starter->rejoin_group(group);
304
305 // update recipient with id, title and members
306@@ -552,6 +645,12 @@
307 error->set(TP_QT_ERROR_CANCELLED, "Group rejoin rejected");
308 return Tp::BaseChannelPtr{};
309 }
310+ catch (...)
311+ {
312+ LOG(ERROR) << "Group rejoin rejected";
313+ error->set(TP_QT_ERROR_CANCELLED, "Group rejoin rejected");
314+ return Tp::BaseChannelPtr{};
315+ }
316 break;
317 }
318 case Tp::HandleTypeNone: {
319@@ -566,7 +665,17 @@
320 hints[TP_QT_IFACE_CHANNEL_INTERFACE_CONFERENCE + QLatin1String(".InitialInviteeIDs")].toStringList();
321 for (QString initial_invitee_id : initial_invitees_ids)
322 {
323- std::string normalized_id = connection->normalize_identifier(initial_invitee_id.toStdString());
324+ std::string normalized_id = initial_invitee_id.toStdString();
325+ try
326+ {
327+ normalized_id = connection->normalize_identifier(normalized_id);
328+ }
329+ catch (...)
330+ {
331+ LOG(ERROR) << "An exception has been thrown when normalizing identifier " << normalized_id
332+ << " using not normalized version";
333+ }
334+
335 //FIXME: get contact attribute display name for the user second param
336 initial_invitees.push_back(std::make_shared<Member>(normalized_id, PendingStatus::Remote, std::string{}/* display_name*/ ));
337 }
338@@ -590,10 +699,10 @@
339 initial_invitees,
340 title);
341
342- std::shared_ptr<GroupStarter> group_starter = connection->group_starter();
343- messaging::Group::shared_ptr group = std::dynamic_pointer_cast<messaging::Group>(recipient);
344 try
345 {
346+ std::shared_ptr<GroupStarter> group_starter = connection->group_starter();
347+ messaging::Group::shared_ptr group = std::dynamic_pointer_cast<messaging::Group>(recipient);
348 group_manager = group_starter->create_group(group);
349
350 // update recipient with id, title and members
351@@ -608,9 +717,16 @@
352 error->set(TP_QT_ERROR_CANCELLED, "Group creation rejected");
353 return Tp::BaseChannelPtr{};
354 }
355+ catch (...)
356+ {
357+ LOG(ERROR) << "Group creation rejected";
358+ error->set(TP_QT_ERROR_CANCELLED, "Group creation rejected");
359+ return Tp::BaseChannelPtr{};
360+ }
361
362 // request handle from group_manager id, filled with the group id after calling start_group()
363- target_handle = request_handles(Tp::HandleTypeRoom, QStringList() << QString::fromStdString(group_manager->group_id()), NULL)[0];
364+ Tp::DBusError error;
365+ target_handle = request_handles(Tp::HandleTypeRoom, QStringList() << QString::fromStdString(group_manager->group_id()), &error)[0];
366 break;
367 }
368 default:
369@@ -619,14 +735,24 @@
370 }
371 }
372
373- return Tp::BaseChannelPtr{mqt::tp::TextChannel::create(
374- this,
375- target_handle,
376- target_handle_type,
377- runtime,
378- connection->messenger(),
379- recipient,
380- group_manager)};
381+ Tp::BaseChannelPtr text_channel;
382+
383+ try
384+ {
385+ text_channel = Tp::BaseChannelPtr{mqt::tp::TextChannel::create(this,
386+ target_handle,
387+ target_handle_type,
388+ runtime,
389+ connection->messenger(),
390+ recipient,
391+ group_manager)};
392+ }
393+ catch (...)
394+ {
395+ LOG(ERROR) << "An exception has been thrown when creating the text channel";
396+ }
397+
398+ return text_channel;
399 }
400
401 Tp::ContactAttributesMap mqt::tp::Connection::get_contact_attributes(const Tp::UIntList &handles, const QStringList &ifaces, Tp::DBusError *error)
402
403=== modified file 'src/messaging/qt/tp/text_channel.cpp'
404--- src/messaging/qt/tp/text_channel.cpp 2016-07-05 13:47:29 +0000
405+++ src/messaging/qt/tp/text_channel.cpp 2016-07-13 04:54:46 +0000
406@@ -87,21 +87,29 @@
407
408 QByteArray read_file_content(const std::string& filename)
409 {
410- std::ifstream fin(filename, std::ifstream::binary);
411- std::ostringstream ostrm;
412- ostrm << fin.rdbuf();
413- std::string data(ostrm.str());
414- return QByteArray(data.data(), data.size());
415+ try
416+ {
417+ std::ifstream fin(filename, std::ifstream::binary);
418+ std::ostringstream ostrm;
419+ ostrm << fin.rdbuf();
420+ std::string data(ostrm.str());
421+ return QByteArray(data.data(), data.size());
422+ }
423+ catch (...)
424+ {
425+ LOG(ERROR) << "An exception has been thrown when reading file " << filename;
426+ return QByteArray();
427+ }
428 }
429
430 messaging::Message make_message(const Tp::MessagePartList &message)
431 {
432 using namespace messaging::qt::tp;
433 messaging::Message mf_message{boost::uuids::to_string(boost::uuids::random_generator()()),
434- std::string(), // sender can be empty on outgoing messages
435- std::string(), // actual message will be filled below
436- std::chrono::system_clock::now(),
437- std::vector<messaging::Attachment>()};
438+ std::string(), // sender can be empty on outgoing messages
439+ std::string(), // actual message will be filled below
440+ std::chrono::system_clock::now(),
441+ std::vector<messaging::Attachment>()};
442 for (auto part : message)
443 {
444 messaging::Attachment attachment;
445@@ -293,8 +301,25 @@
446 }
447
448 // is this needed, or should we use same observer than the used for the chat when plugged as chat interface?
449- group_manager->set_observer(observer);
450- chat->plug_interface(group_manager);
451+ try
452+ {
453+ group_manager->set_observer(observer);
454+ }
455+ catch (...)
456+ {
457+ LOG(ERROR) << "An exception has been thrown when setting group manager observer";
458+ return;
459+ }
460+
461+ try
462+ {
463+ chat->plug_interface(group_manager);
464+ }
465+ catch (...)
466+ {
467+ LOG(ERROR) << "An exception has been thrown when pluging in group manager as chat interface";
468+ return;
469+ }
470
471 // initialize the telepathy room interface
472 messaging::Group::shared_ptr group = std::dynamic_pointer_cast<messaging::Group>(recipient);
473@@ -308,15 +333,38 @@
474 /* creatorHandle */ 0,
475 /* creationTimestamp */ QDateTime());
476 room_config_interface = Tp::BaseChannelRoomConfigInterface::create();
477- room_config_interface->setTitle(QString::fromStdString(group_manager->group_title()));
478+
479+ try
480+ {
481+ room_config_interface->setTitle(QString::fromStdString(group_manager->group_title()));
482+ }
483+ catch (...)
484+ {
485+ LOG(ERROR) << "An exception has been thrown when setting group title";
486+ return;
487+ }
488+
489 room_config_interface->setConfigurationRetrieved(true);
490 room_config_interface->setCanUpdateConfiguration(true);
491
492 // FIXME: check what flags we want by default
493- Tp::ChannelGroupFlags groupFlags = Tp::ChannelGroupFlagCanAdd|Tp::ChannelGroupFlagCanRemove|Tp::ChannelGroupFlagHandleOwnersNotAvailable|Tp::ChannelGroupFlagMembersChangedDetailed|Tp::ChannelGroupFlagProperties;
494+ Tp::ChannelGroupFlags groupFlags = Tp::ChannelGroupFlagCanAdd |
495+ Tp::ChannelGroupFlagCanRemove |
496+ Tp::ChannelGroupFlagHandleOwnersNotAvailable |
497+ Tp::ChannelGroupFlagMembersChangedDetailed |
498+ Tp::ChannelGroupFlagProperties;
499 group_interface = Tp::BaseChannelGroupInterface::create();
500 group_interface->setGroupFlags(groupFlags);
501- group_interface->setSelfHandle(tp_connection->selfHandle());
502+
503+ try
504+ {
505+ group_interface->setSelfHandle(tp_connection->selfHandle());
506+ }
507+ catch (...)
508+ {
509+ LOG(ERROR) << "An exception has been thrown when setting group self handle";
510+ return;
511+ }
512
513 // we need to plug this interface here to avoid a crash
514 plug_interface_if_available(group_interface);
515@@ -350,60 +398,69 @@
516
517 void mqt::tp::TextChannel::on_message_received(const messaging::Message& message)
518 {
519- auto time = std::chrono::system_clock::now();
520-
521- Tp::MessagePartList parts;
522- Tp::MessagePart header;
523- header["message-token"] = QDBusVariant(QString::fromStdString(message.id));
524- header["message-received"] = QDBusVariant(static_cast<uint>(std::chrono::system_clock::to_time_t(time)));
525- if (targetHandleType() == Tp::HandleTypeContact) {
526- header["message-sender"] = QDBusVariant((qulonglong)targetHandle());
527- } else {
528- uint id = tp_connection->requestHandles(Tp::HandleTypeContact, QStringList() << QString::fromStdString(message.sender), 0)[0];
529- header["message-sender"] = QDBusVariant(id);
530- }
531- header["message-type"] = QDBusVariant(Tp::ChannelTextMessageTypeNormal);
532-
533- parts << header;
534-
535- bool has_pending_file_transfer = false;
536- for (auto attachment : message.attachments) {
537- Tp::MessagePart part;
538- QString contentType;
539- QByteArray content(attachment.content->as_data(), attachment.content->data_size());
540- if (attachment.content_type.empty()) {
541- contentType = guess_content_type(content);
542- } else {
543- contentType = QString::fromStdString(attachment.content_type);
544- }
545- part[message::keys::content_type] = QDBusVariant(contentType);
546- part[message::keys::content] = QDBusVariant(content);
547- part[message::keys::identifier] = QDBusVariant(QString::fromStdString(attachment.id));
548- if (attachment.status == messaging::AttachmentStatus::AttachmentPending) {
549- has_pending_file_transfer = true;
550- part[message::keys::size] = QDBusVariant(QVariant::fromValue(attachment.size));
551- part[message::keys::needs_retrieval] = QDBusVariant(true);
552- // for now we trigger the download ourselves, but we need to
553- // allow clients to do that
554- part[message::keys::filename] = QDBusVariant(QString::fromStdString((chat->download_file(attachment.id))));
555- }
556- parts << part;
557- }
558-
559- // check if comes text into message.message and add a text plain part if so
560- if (!message.message.empty()) {
561- Tp::MessagePart text_part;
562- text_part[message::keys::content_type] = QDBusVariant("text/plain");
563- text_part[message::keys::identifier] = QDBusVariant("text_0.txt");
564- text_part[message::keys::content] = QDBusVariant(QString::fromStdString(message.message));
565- text_part[message::keys::size] = QDBusVariant(QVariant::fromValue((qulonglong)message.message.length()));
566- parts << text_part;
567- }
568-
569- if (has_pending_file_transfer) {
570- pending_messages[message.id] = parts;
571- } else {
572- text_type_interface->addReceivedMessage(parts);
573+ try
574+ {
575+ auto time = std::chrono::system_clock::now();
576+
577+ Tp::MessagePartList parts;
578+ Tp::MessagePart header;
579+ header["message-token"] = QDBusVariant(QString::fromStdString(message.id));
580+ header["message-received"] = QDBusVariant(static_cast<uint>(std::chrono::system_clock::to_time_t(time)));
581+ if (targetHandleType() == Tp::HandleTypeContact) {
582+ header["message-sender"] = QDBusVariant((qulonglong)targetHandle());
583+ } else {
584+ Tp::DBusError error;
585+ uint id = tp_connection->requestHandles(Tp::HandleTypeContact, QStringList() << QString::fromStdString(message.sender), &error)[0];
586+ header["message-sender"] = QDBusVariant(id);
587+ }
588+ header["message-type"] = QDBusVariant(Tp::ChannelTextMessageTypeNormal);
589+
590+ parts << header;
591+
592+ bool has_pending_file_transfer = false;
593+ for (auto attachment : message.attachments) {
594+ Tp::MessagePart part;
595+ QString contentType;
596+ QByteArray content(attachment.content->as_data(), attachment.content->data_size());
597+ if (attachment.content_type.empty()) {
598+ contentType = guess_content_type(content);
599+ } else {
600+ contentType = QString::fromStdString(attachment.content_type);
601+ }
602+ part[message::keys::content_type] = QDBusVariant(contentType);
603+ part[message::keys::content] = QDBusVariant(content);
604+ part[message::keys::identifier] = QDBusVariant(QString::fromStdString(attachment.id));
605+ if (attachment.status == messaging::AttachmentStatus::AttachmentPending) {
606+ has_pending_file_transfer = true;
607+ part[message::keys::size] = QDBusVariant(QVariant::fromValue(attachment.size));
608+ part[message::keys::needs_retrieval] = QDBusVariant(true);
609+ // for now we trigger the download ourselves, but we need to
610+ // allow clients to do that
611+ part[message::keys::filename] = QDBusVariant(QString::fromStdString((chat->download_file(attachment.id))));
612+ }
613+ parts << part;
614+ }
615+
616+ // check if comes text into message.message and add a text plain part if so
617+ if (!message.message.empty()) {
618+ Tp::MessagePart text_part;
619+ text_part[message::keys::content_type] = QDBusVariant("text/plain");
620+ text_part[message::keys::identifier] = QDBusVariant("text_0.txt");
621+ text_part[message::keys::content] = QDBusVariant(QString::fromStdString(message.message));
622+ text_part[message::keys::size] = QDBusVariant(QVariant::fromValue((qulonglong)message.message.length()));
623+ parts << text_part;
624+ }
625+
626+ if (has_pending_file_transfer) {
627+ pending_messages[message.id] = parts;
628+ } else {
629+ text_type_interface->addReceivedMessage(parts);
630+ }
631+
632+ }
633+ catch (...)
634+ {
635+ LOG(ERROR) << "An exception has happened when evaluating a received message";
636 }
637 }
638
639@@ -633,61 +690,85 @@
640 catch (const std::exception& e)
641 {
642 error->set(TP_QT_ERROR_NOT_AVAILABLE, QString::fromStdString(e.what()));
643+ LOG(ERROR) << "An exception has been thrown when sending a message: " << e.what();
644 return the_invalid_id;
645 }
646 catch (...)
647 {
648+ LOG(ERROR) << "An exception has been thrown when sending a message";
649+ error->set(TP_QT_ERROR_NOT_AVAILABLE, "");
650+ return the_invalid_id;
651 }
652-
653- error->set(TP_QT_ERROR_NOT_AVAILABLE, "");
654- return the_invalid_id;
655 }
656
657 void mqt::tp::TextChannel::message_acknowledged(const QString &id)
658 {
659 std::cout << __PRETTY_FUNCTION__ << std::endl;
660- chat->mark_message_as_read(id.toStdString());
661+ try
662+ {
663+ chat->mark_message_as_read(id.toStdString());
664+ }
665+ catch (...)
666+ {
667+ LOG(ERROR) << "An exception has been thrown when marking message as read";
668+ }
669 }
670
671 void mqt::tp::TextChannel::add_members(const Tp::UIntList& handles, const QString& message, Tp::DBusError* error)
672 {
673 Q_UNUSED(message);
674- std::shared_ptr<messaging::GroupManager> group_manager = chat->interface<GroupManager>();
675-
676- if (!group_manager) {
677- error->set(TP_QT_ERROR_NOT_AVAILABLE, "Text channel is not a room");
678- return;
679- }
680-
681- QStringList ids = tp_connection->inspectHandles(Tp::HandleTypeContact, handles, 0);
682- messaging::Members members;
683- for (QString id : ids)
684- {
685- members.push_back(std::make_shared<messaging::Member>(id.toStdString()));
686- }
687-
688- group_manager->add_members(members);
689+
690+ try
691+ {
692+ std::shared_ptr<messaging::GroupManager> group_manager = chat->interface<GroupManager>();
693+
694+ if (!group_manager) {
695+ error->set(TP_QT_ERROR_NOT_AVAILABLE, "Text channel is not a room");
696+ return;
697+ }
698+
699+ QStringList ids = tp_connection->inspectHandles(Tp::HandleTypeContact, handles, 0);
700+ messaging::Members members;
701+ for (QString id : ids)
702+ {
703+ members.push_back(std::make_shared<messaging::Member>(id.toStdString()));
704+ }
705+
706+ group_manager->add_members(members);
707+ }
708+ catch (...)
709+ {
710+ LOG(ERROR) << "An exception has been thrown when trying to add members to a group";
711+ }
712 }
713
714 void mqt::tp::TextChannel::remove_members(const Tp::UIntList& handles, const QString& message, uint reason, Tp::DBusError* error)
715 {
716 Q_UNUSED(message);
717 Q_UNUSED(reason);
718- std::shared_ptr<messaging::GroupManager> group_manager = chat->interface<GroupManager>();
719-
720- if (!group_manager) {
721- error->set(TP_QT_ERROR_NOT_AVAILABLE, "Text channel is not a room");
722- return;
723- }
724-
725- QStringList ids = tp_connection->inspectHandles(Tp::HandleTypeContact, handles, 0);
726- messaging::Members members;
727- for (QString id : ids)
728- {
729- members.push_back(std::make_shared<messaging::Member>(id.toStdString()));
730- }
731-
732- group_manager->remove_members(members);
733+
734+ try
735+ {
736+ std::shared_ptr<messaging::GroupManager> group_manager = chat->interface<GroupManager>();
737+
738+ if (!group_manager) {
739+ error->set(TP_QT_ERROR_NOT_AVAILABLE, "Text channel is not a room");
740+ return;
741+ }
742+
743+ QStringList ids = tp_connection->inspectHandles(Tp::HandleTypeContact, handles, 0);
744+ messaging::Members members;
745+ for (QString id : ids)
746+ {
747+ members.push_back(std::make_shared<messaging::Member>(id.toStdString()));
748+ }
749+
750+ group_manager->remove_members(members);
751+ }
752+ catch (...)
753+ {
754+ LOG(ERROR) << "An exception has been thrown when trying to remove members from a group";
755+ }
756 }
757
758
759@@ -695,17 +776,24 @@
760 {
761 Q_UNUSED(error);
762
763- switch (state) {
764- case Tp::ChannelChatStateComposing:
765- chat->start_typing();
766- break;
767- case Tp::ChannelChatStateActive:
768- case Tp::ChannelChatStateGone:
769- case Tp::ChannelChatStateInactive:
770- case Tp::ChannelChatStatePaused:
771- default:
772- chat->end_typing();
773- break;
774+ try
775+ {
776+ switch (state) {
777+ case Tp::ChannelChatStateComposing:
778+ chat->start_typing();
779+ break;
780+ case Tp::ChannelChatStateActive:
781+ case Tp::ChannelChatStateGone:
782+ case Tp::ChannelChatStateInactive:
783+ case Tp::ChannelChatStatePaused:
784+ default:
785+ chat->end_typing();
786+ break;
787+ }
788+ }
789+ catch (...)
790+ {
791+ LOG(ERROR) << "An exception has been thrown when updating typing signal";
792 }
793 }
794
795@@ -717,30 +805,43 @@
796 return;
797 }
798
799- std::shared_ptr<messaging::GroupManager> group_manager = chat->interface<GroupManager>();
800- if (!group_manager) {
801- error->set(TP_QT_ERROR_NOT_AVAILABLE, "Text channel is not a room");
802- return;
803- }
804+ try
805+ {
806+ std::shared_ptr<messaging::GroupManager> group_manager = chat->interface<GroupManager>();
807+ if (!group_manager) {
808+ error->set(TP_QT_ERROR_NOT_AVAILABLE, "Text channel is not a room");
809+ return;
810+ }
811
812- group_manager->change_group_title(properties["Title"].toString().toStdString());
813+ group_manager->change_group_title(properties["Title"].toString().toStdString());
814+ }
815+ catch (...)
816+ {
817+ LOG(ERROR) << "An exception has been thrown when updating group configuration";
818+ }
819 }
820
821 void mqt::tp::TextChannel::destroy(Tp::DBusError* error)
822 {
823- std::shared_ptr<messaging::GroupManager> group_manager = chat->interface<GroupManager>();
824- if (!group_manager) {
825- error->set(TP_QT_ERROR_NOT_AVAILABLE, "Text channel is not a room");
826- return;
827- }
828-
829 try
830 {
831+ std::shared_ptr<messaging::GroupManager> group_manager = chat->interface<GroupManager>();
832+ if (!group_manager) {
833+ error->set(TP_QT_ERROR_NOT_AVAILABLE, "Text channel is not a room");
834+ return;
835+ }
836+
837 group_manager->dissolve_group();
838 }
839 catch (const std::exception& e)
840 {
841 error->set(TP_QT_ERROR_RESOURCE_UNAVAILABLE, QString("Failed to destroy: %1").arg(e.what()));
842+ LOG(ERROR) << "An exception has been thrown when destroying a group: " << e.what();
843+ }
844+ catch (...)
845+ {
846+ error->set(TP_QT_ERROR_RESOURCE_UNAVAILABLE, QString("Failed to destroy"));
847+ LOG(ERROR) << "An exception has been thrown when destroying a group";
848 }
849 }
850

Subscribers

People subscribed via source and target branches

to all changes: