1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
use crate::msg_types;
use crate::{Error, ErrorKind, InvalidLogin};
use ffi_support::{implement_into_ffi_by_protobuf, ErrorCode, ExternError};
use sync15::ErrorKind as Sync15ErrorKind;
pub mod error_codes {
pub const UNEXPECTED: i32 = -2;
pub const AUTH_INVALID: i32 = 1;
pub const NO_SUCH_RECORD: i32 = 2;
pub const DUPLICATE_GUID: i32 = 3;
pub const INVALID_KEY: i32 = 4;
pub const NETWORK: i32 = 5;
pub const INTERRUPTED: i32 = 6;
pub const INVALID_SALT: i32 = 7;
pub const INVALID_LOGIN_EMPTY_ORIGIN: i32 = 64;
pub const INVALID_LOGIN_EMPTY_PASSWORD: i32 = 64 + 1;
pub const INVALID_LOGIN_DUPLICATE_LOGIN: i32 = 64 + 2;
pub const INVALID_LOGIN_BOTH_TARGETS: i32 = 64 + 3;
pub const INVALID_LOGIN_NO_TARGET: i32 = 64 + 4;
pub const INVALID_LOGIN_ILLEGAL_FIELD_VALUE: i32 = 64 + 5;
}
fn get_code(err: &Error) -> ErrorCode {
match err.kind() {
ErrorKind::SyncAdapterError(e) => {
log::error!("Sync error {:?}", e);
match e.kind() {
Sync15ErrorKind::TokenserverHttpError(401) | Sync15ErrorKind::BadKeyLength(..) => {
ErrorCode::new(error_codes::AUTH_INVALID)
}
Sync15ErrorKind::RequestError(_) => ErrorCode::new(error_codes::NETWORK),
_ => ErrorCode::new(error_codes::UNEXPECTED),
}
}
ErrorKind::DuplicateGuid(id) => {
log::error!("Guid already exists: {}", id);
ErrorCode::new(error_codes::DUPLICATE_GUID)
}
ErrorKind::NoSuchRecord(id) => {
log::error!("No record exists with id {}", id);
ErrorCode::new(error_codes::NO_SUCH_RECORD)
}
ErrorKind::InvalidLogin(desc) => {
log::error!("Invalid login: {}", desc);
ErrorCode::new(match desc {
InvalidLogin::EmptyOrigin => error_codes::INVALID_LOGIN_EMPTY_ORIGIN,
InvalidLogin::EmptyPassword => error_codes::INVALID_LOGIN_EMPTY_PASSWORD,
InvalidLogin::DuplicateLogin => error_codes::INVALID_LOGIN_DUPLICATE_LOGIN,
InvalidLogin::BothTargets => error_codes::INVALID_LOGIN_BOTH_TARGETS,
InvalidLogin::NoTarget => error_codes::INVALID_LOGIN_NO_TARGET,
InvalidLogin::IllegalFieldValue { .. } => {
error_codes::INVALID_LOGIN_ILLEGAL_FIELD_VALUE
}
})
}
ErrorKind::SqlError(rusqlite::Error::SqliteFailure(err, _))
if err.code == rusqlite::ErrorCode::NotADatabase =>
{
log::error!("Not a database / invalid key error");
ErrorCode::new(error_codes::INVALID_KEY)
}
ErrorKind::SqlError(rusqlite::Error::SqliteFailure(err, _))
if err.code == rusqlite::ErrorCode::OperationInterrupted =>
{
log::warn!("Operation interrupted (SQL)");
ErrorCode::new(error_codes::INTERRUPTED)
}
ErrorKind::Interrupted(_) => {
log::warn!("Operation interrupted (Outside SQL)");
ErrorCode::new(error_codes::INTERRUPTED)
}
ErrorKind::InvalidSalt => {
log::error!("Invalid salt provided");
ErrorCode::new(error_codes::INVALID_SALT)
}
err => {
log::error!("Unexpected error: {:?}", err);
ErrorCode::new(error_codes::UNEXPECTED)
}
}
}
impl From<Error> for ExternError {
fn from(e: Error) -> ExternError {
ExternError::new_error(get_code(&e), e.to_string())
}
}
implement_into_ffi_by_protobuf!(msg_types::PasswordInfo);
implement_into_ffi_by_protobuf!(msg_types::PasswordInfos);