• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

realm / realm-core / michael.wilkersonbarker_1333

13 Aug 2024 02:19AM UTC coverage: 91.097% (-0.01%) from 91.107%
michael.wilkersonbarker_1333

Pull #7982

Evergreen

michael-wb
Updates from review
Pull Request #7982: Add missing protocol errors

102828 of 181646 branches covered (56.61%)

2 of 5 new or added lines in 1 file covered. (40.0%)

82 existing lines in 12 files now uncovered.

217366 of 238609 relevant lines covered (91.1%)

6057728.34 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

35.22
/src/realm/sync/protocol.cpp
1
#include <realm/sync/protocol.hpp>
2

3

4
namespace realm::sync {
5

6
const char* get_protocol_error_message(int error_code) noexcept
7
{
176✔
8
    // FIXME: These human-readable messages are phrased from the perspective of the client, but they may occur on the
9
    // server side as well.
10

11
    switch (ProtocolError(error_code)) {
176✔
12
        case ProtocolError::connection_closed:
68✔
13
            return "Connection closed (no error)";
68✔
14
        case ProtocolError::other_error:
12✔
15
            return "Other connection level error";
12✔
16
        case ProtocolError::unknown_message:
✔
17
            return "Unknown type of input message";
×
18
        case ProtocolError::bad_syntax:
✔
19
            return "Bad syntax in input message head";
×
20
        case ProtocolError::limits_exceeded:
✔
21
            return "Limits exceeded in input message";
×
22
        case ProtocolError::wrong_protocol_version:
✔
23
            return "Wrong protocol version (CLIENT)";
×
24
        case ProtocolError::bad_session_ident:
✔
25
            return "The server has forgotten about this session (Bad session identifier in input message). "
×
26
                   "Restart the client to resume synchronization";
×
27
        case ProtocolError::reuse_of_session_ident:
✔
28
            return "An existing synchronization session exists with this session identifier (Overlapping reuse of "
×
29
                   "session identifier (BIND)).";
×
30
        case ProtocolError::bound_in_other_session:
✔
31
            return "An existing synchronization session exists for this client-side file (Client file bound in other "
×
32
                   "session (IDENT))";
×
33
        case ProtocolError::bad_message_order:
✔
34
            return "Bad input message order";
×
35
        case ProtocolError::bad_decompression:
✔
36
            return "The server sent an invalid DOWNLOAD message (Bad decompression of message)";
×
37
        case ProtocolError::bad_changeset_header_syntax:
✔
38
            return "The server sent an invalid DOWNLOAD message (Bad changeset header syntax)";
×
39
        case ProtocolError::bad_changeset_size:
✔
40
            return "The server sent an invalid DOWNLOAD message (Bad changeset size)";
×
41
        case ProtocolError::switch_to_flx_sync:
6✔
42
            return "Wrong wire protocol, switch to the flexible sync wire protocol";
6✔
43
        case ProtocolError::switch_to_pbs:
12✔
44
            return "Wrong wire protocol, switch to the partition-based sync wire protocol";
12✔
45

46
        case ProtocolError::session_closed:
✔
47
            return "Session closed (no error)";
×
48
        case ProtocolError::other_session_error:
✔
49
            return "Other session level error";
×
50
        case ProtocolError::token_expired:
✔
51
            return "Access token expired";
×
52
        case ProtocolError::bad_authentication:
✔
53
            return "Bad user authentication (BIND)";
×
54
        case ProtocolError::illegal_realm_path:
28✔
55
            return "Illegal Realm path (BIND)";
28✔
56
        case ProtocolError::no_such_realm:
✔
57
            return "No such Realm (BIND)";
×
58
        case ProtocolError::permission_denied:
✔
59
            return "Permission denied (BIND)";
×
60
        case ProtocolError::bad_server_file_ident:
✔
61
            return "The server sent an obsolete error code (Bad server file identifier (IDENT))";
×
62
        case ProtocolError::bad_client_file_ident:
✔
63
            return "The server has forgotten about this client-side file (Bad client file identifier (IDENT)). "
×
64
                   "Please wipe the file on the client to resume synchronization";
×
65
        case ProtocolError::bad_server_version:
20✔
66
            return "The client is ahead of the server (Bad server version (IDENT, UPLOAD)). Please wipe the file on "
20✔
67
                   "the client to resume synchronization";
20✔
68
        case ProtocolError::bad_client_version:
4✔
69
            return "The server claimed to have received changesets from this client that the client has not produced "
4✔
70
                   "yet (Bad client version (IDENT, UPLOAD)). Please wipe the file on the client to resume "
4✔
71
                   "synchronization";
4✔
72
        case ProtocolError::diverging_histories:
8✔
73
            return "The client and server disagree about the history (Diverging histories (IDENT)). Please wipe the "
8✔
74
                   "file on the client to resume synchronization";
8✔
75
        case ProtocolError::bad_changeset:
14✔
76
            return "The server sent a changeset that could not be integrated (Bad changeset (UPLOAD, ERROR)). This "
14✔
77
                   "is likely due to corruption of the client-side file. Please restore the file on the client by "
14✔
78
                   "wiping it and resuming synchronization";
14✔
79
        case ProtocolError::partial_sync_disabled:
✔
80
            return "Query-based sync is disabled";
×
81
        case ProtocolError::unsupported_session_feature:
✔
82
            return "Unsupported session-level feature";
×
83
        case ProtocolError::bad_origin_file_ident:
✔
84
            return "The server sent an obsolete error code (Bad origin file identifier (UPLOAD))";
×
85
        case ProtocolError::bad_client_file:
✔
86
            return "Synchronization no longer possible for client-side file. Please wipe the file on the client to "
×
87
                   "resume synchronization";
×
88
        case ProtocolError::server_file_deleted:
✔
89
            return "Server file was deleted while a session was bound to it";
×
90
        case ProtocolError::client_file_blacklisted:
✔
91
            return "Client file has been blacklisted (IDENT)";
×
92
        case ProtocolError::user_blacklisted:
✔
93
            return "User has been blacklisted (BIND)";
×
94
        case ProtocolError::transact_before_upload:
✔
95
            return "The server sent an obsolete error code (Serialized transaction before upload completion)";
×
96
        case ProtocolError::client_file_expired:
✔
97
            return "Client file has expired due to log compaction. Please wipe the file on the client to resume "
×
98
                   "synchronization";
×
99
        case ProtocolError::user_mismatch:
✔
100
            return "User mismatch for client file identifier (IDENT)";
×
101
        case ProtocolError::too_many_sessions:
✔
102
            return "Too many sessions in connection (BIND)";
×
103
        case ProtocolError::invalid_schema_change:
✔
104
            return "Invalid schema change (UPLOAD)";
×
105
        case ProtocolError::bad_query:
✔
106
            return "Client query is invalid/malformed (IDENT, QUERY)";
×
107
        case ProtocolError::object_already_exists:
✔
108
            return "Client tried to create an object that already exists outside their view (UPLOAD)";
×
109
        case ProtocolError::server_permissions_changed:
✔
110
            return "Server permissions for this file ident have changed since the last time it was used (IDENT)";
×
111
        case ProtocolError::initial_sync_not_completed:
✔
112
            return "Client tried to open a session before initial sync is complete (BIND)";
×
113
        case ProtocolError::write_not_allowed:
✔
114
            return "Client attempted a write that is disallowed by permissions, or modifies an object outside the "
×
115
                   "current query - requires client reset";
×
116
        case ProtocolError::compensating_write:
✔
117
            return "Client attempted a write that is disallowed by permissions, or modifies an object outside the "
×
118
                   "current query, and the server undid the change";
×
119
        case ProtocolError::migrate_to_flx:
✔
120
            return "Server migrated to flexible sync - migrating client to use flexible sync";
×
121
        case ProtocolError::bad_progress:
✔
122
            return "Bad progress information (DOWNLOAD)";
×
123
        case ProtocolError::revert_to_pbs:
✔
124
            return "Server rolled back after flexible sync migration - reverting client to partition based "
×
125
                   "sync";
×
126
        case ProtocolError::bad_schema_version:
✔
127
            return "Client tried to open a session with an invalid schema version (BIND)";
×
128
        case ProtocolError::schema_version_changed:
✔
129
            return "Client opened a session with a new valid schema version - migrating client to use new schema "
×
130
                   "version (BIND)";
×
NEW
131
        case ProtocolError::schema_version_force_upgrade:
✔
NEW
132
            return "Server has forcefully bumped client's schema version because it does not support schema "
×
NEW
133
                   "versioning";
×
134
    }
176✔
135
    return nullptr;
4✔
136
}
176✔
137

138
std::ostream& operator<<(std::ostream& os, ProtocolError error)
139
{
×
140
    if (auto str = get_protocol_error_message(static_cast<int>(error))) {
×
141
        return os << str;
×
142
    }
×
143
    return os << "Unknown protocol error " << static_cast<int>(error);
×
144
}
×
145

146
Status protocol_error_to_status(ProtocolError error_code, std::string_view msg)
147
{
1,102✔
148
    auto translated_error_code = [&] {
1,102✔
149
        switch (error_code) {
1,102✔
150
            case ProtocolError::connection_closed:
36✔
151
                return ErrorCodes::ConnectionClosed;
36✔
152
            case ProtocolError::other_error:
12✔
153
                return ErrorCodes::RuntimeError;
12✔
154
            case ProtocolError::unknown_message:
✔
155
                [[fallthrough]];
×
156
            case ProtocolError::bad_syntax:
✔
157
                [[fallthrough]];
×
158
            case ProtocolError::wrong_protocol_version:
✔
159
                [[fallthrough]];
×
160
            case ProtocolError::bad_session_ident:
✔
161
                [[fallthrough]];
×
162
            case ProtocolError::reuse_of_session_ident:
✔
163
                [[fallthrough]];
×
164
            case ProtocolError::bound_in_other_session:
✔
165
                [[fallthrough]];
×
166
            case ProtocolError::bad_changeset_header_syntax:
✔
167
                [[fallthrough]];
×
168
            case ProtocolError::bad_changeset_size:
✔
169
                [[fallthrough]];
×
170
            case ProtocolError::bad_message_order:
✔
171
                return ErrorCodes::SyncProtocolInvariantFailed;
×
172
            case ProtocolError::bad_decompression:
✔
173
                return ErrorCodes::RuntimeError;
×
174
            case ProtocolError::switch_to_flx_sync:
6✔
175
                [[fallthrough]];
6✔
176
            case ProtocolError::switch_to_pbs:
18✔
177
                return ErrorCodes::WrongSyncType;
18✔
178

179
            case ProtocolError::session_closed:
142✔
180
                return ErrorCodes::ConnectionClosed;
142✔
181
            case ProtocolError::other_session_error:
4✔
182
                return ErrorCodes::RuntimeError;
4✔
183
            case ProtocolError::illegal_realm_path:
32✔
184
                return ErrorCodes::BadSyncPartitionValue;
32✔
185
            case ProtocolError::permission_denied:
✔
186
                return ErrorCodes::SyncPermissionDenied;
×
187
            case ProtocolError::bad_client_file_ident:
392✔
188
                [[fallthrough]];
392✔
189
            case ProtocolError::bad_server_version:
420✔
190
                [[fallthrough]];
420✔
191
            case ProtocolError::bad_client_version:
424✔
192
                [[fallthrough]];
424✔
193
            case ProtocolError::diverging_histories:
440✔
194
                [[fallthrough]];
440✔
195
            case ProtocolError::client_file_expired:
440✔
196
                [[fallthrough]];
440✔
197
            case ProtocolError::bad_client_file:
448✔
198
                return ErrorCodes::SyncClientResetRequired;
448✔
199
            case ProtocolError::bad_changeset:
4✔
200
                return ErrorCodes::BadChangeset;
4✔
201
            case ProtocolError::bad_origin_file_ident:
✔
202
                return ErrorCodes::SyncProtocolInvariantFailed;
×
203
            case ProtocolError::user_mismatch:
✔
204
                return ErrorCodes::SyncUserMismatch;
×
205
            case ProtocolError::invalid_schema_change:
12✔
206
                return ErrorCodes::InvalidSchemaChange;
12✔
207
            case ProtocolError::bad_query:
✔
208
                return ErrorCodes::InvalidSubscriptionQuery;
×
209
            case ProtocolError::object_already_exists:
✔
210
                return ErrorCodes::ObjectAlreadyExists;
×
211
            case ProtocolError::server_permissions_changed:
✔
212
                return ErrorCodes::SyncServerPermissionsChanged;
×
213
            case ProtocolError::initial_sync_not_completed:
22✔
214
                return ErrorCodes::ConnectionClosed;
22✔
215
            case ProtocolError::write_not_allowed:
4✔
216
                return ErrorCodes::SyncWriteNotAllowed;
4✔
217
            case ProtocolError::compensating_write:
124✔
218
                return ErrorCodes::SyncCompensatingWrite;
124✔
219
            case ProtocolError::bad_progress:
✔
220
                return ErrorCodes::SyncProtocolInvariantFailed;
×
221
            case ProtocolError::migrate_to_flx:
36✔
222
                [[fallthrough]];
36✔
223
            case ProtocolError::revert_to_pbs:
56✔
224
                return ErrorCodes::WrongSyncType;
56✔
225
            case ProtocolError::bad_schema_version:
32✔
226
                [[fallthrough]];
32✔
227
            case ProtocolError::schema_version_changed:
168✔
228
                [[fallthrough]];
168✔
229
            case ProtocolError::schema_version_force_upgrade:
168✔
230
                return ErrorCodes::SyncSchemaMigrationError;
168✔
231

232
            case ProtocolError::limits_exceeded:
✔
233
                [[fallthrough]];
×
234
            case ProtocolError::token_expired:
✔
235
                [[fallthrough]];
×
236
            case ProtocolError::bad_authentication:
✔
237
                [[fallthrough]];
×
238
            case ProtocolError::no_such_realm:
✔
239
                [[fallthrough]];
×
240
            case ProtocolError::bad_server_file_ident:
✔
241
                [[fallthrough]];
×
242
            case ProtocolError::partial_sync_disabled:
✔
243
                [[fallthrough]];
×
244
            case ProtocolError::unsupported_session_feature:
✔
245
                [[fallthrough]];
×
246
            case ProtocolError::too_many_sessions:
✔
247
                [[fallthrough]];
×
248
            case ProtocolError::server_file_deleted:
✔
249
                [[fallthrough]];
×
250
            case ProtocolError::client_file_blacklisted:
✔
251
                [[fallthrough]];
×
252
            case ProtocolError::user_blacklisted:
✔
253
                [[fallthrough]];
×
254
            case ProtocolError::transact_before_upload:
✔
255
                REALM_UNREACHABLE();
256
        }
1,102✔
257
        return ErrorCodes::UnknownError;
20✔
258
    }();
1,102✔
259

260
    if (translated_error_code == ErrorCodes::UnknownError) {
1,102✔
261
        return {ErrorCodes::UnknownError,
20✔
262
                util::format("Unknown sync protocol error code %1: %2", static_cast<int>(error_code), msg)};
20✔
263
    }
20✔
264
    return {translated_error_code, msg};
1,082✔
265
}
1,102✔
266

267
} // namespace realm::sync
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc