diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/ConnectViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/ConnectViewModel.kt index 296437203e40..325ee42b431d 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/ConnectViewModel.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/ConnectViewModel.kt @@ -123,15 +123,19 @@ class ConnectViewModel( } fun onDisconnectClick() { - viewModelScope.launch { connectionProxy.disconnect().onLeft { - _uiSideEffect.send(UiSideEffect.ConnectError.Generic) - } } + viewModelScope.launch { + connectionProxy.disconnect().onLeft { + _uiSideEffect.send(UiSideEffect.ConnectError.Generic) + } + } } fun onReconnectClick() { - viewModelScope.launch { connectionProxy.reconnect().onLeft { - _uiSideEffect.send(UiSideEffect.ConnectError.Generic) - } } + viewModelScope.launch { + connectionProxy.reconnect().onLeft { + _uiSideEffect.send(UiSideEffect.ConnectError.Generic) + } + } } fun onConnectClick() { @@ -160,9 +164,11 @@ class ConnectViewModel( } fun onCancelClick() { - viewModelScope.launch { connectionProxy.disconnect().onLeft { - _uiSideEffect.send(UiSideEffect.ConnectError.Generic) - } } + viewModelScope.launch { + connectionProxy.disconnect().onLeft { + _uiSideEffect.send(UiSideEffect.ConnectError.Generic) + } + } } fun onManageAccountClick() { diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/OutOfTimeViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/OutOfTimeViewModel.kt index 887ee8084aa5..dfa4e6e3cc35 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/OutOfTimeViewModel.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/OutOfTimeViewModel.kt @@ -72,9 +72,9 @@ class OutOfTimeViewModel( } fun onDisconnectClick() { - viewModelScope.launch { connectionProxy.disconnect().onLeft { - _uiSideEffect.send(UiSideEffect.GenericError) - } } + viewModelScope.launch { + connectionProxy.disconnect().onLeft { _uiSideEffect.send(UiSideEffect.GenericError) } + } } private fun verifyPurchases() { diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/WelcomeViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/WelcomeViewModel.kt index 89593fb58331..e532045ae280 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/WelcomeViewModel.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/WelcomeViewModel.kt @@ -78,9 +78,9 @@ class WelcomeViewModel( } fun onDisconnectClick() { - viewModelScope.launch { connectionProxy.disconnect().onLeft { - _uiSideEffect.send(UiSideEffect.GenericError) - } } + viewModelScope.launch { + connectionProxy.disconnect().onLeft { _uiSideEffect.send(UiSideEffect.GenericError) } + } } private fun verifyPurchases() { diff --git a/android/lib/daemon-grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/daemon/grpc/ManagementService.kt b/android/lib/daemon-grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/daemon/grpc/ManagementService.kt index 00357c1f9bd5..a15d380dfbb8 100644 --- a/android/lib/daemon-grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/daemon/grpc/ManagementService.kt +++ b/android/lib/daemon-grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/daemon/grpc/ManagementService.kt @@ -78,8 +78,8 @@ import net.mullvad.mullvadvpn.lib.model.GetDeviceListError import net.mullvad.mullvadvpn.lib.model.GetDeviceStateError import net.mullvad.mullvadvpn.lib.model.GetVersionInfoError import net.mullvad.mullvadvpn.lib.model.LoginAccountError -import net.mullvad.mullvadvpn.lib.model.NameAlreadyExists import net.mullvad.mullvadvpn.lib.model.LogoutAccountError +import net.mullvad.mullvadvpn.lib.model.NameAlreadyExists import net.mullvad.mullvadvpn.lib.model.NewAccessMethodSetting import net.mullvad.mullvadvpn.lib.model.ObfuscationSettings import net.mullvad.mullvadvpn.lib.model.Ownership as ModelOwnership @@ -246,16 +246,19 @@ class ManagementService( suspend fun getDevice(): Either = Either.catch { grpc.getDevice(Empty.getDefaultInstance()) } .map { it.toDomain() } + .onLeft { Logger.e("Get device error", it) } .mapLeft { GetDeviceStateError.Unknown(it) } suspend fun updateDevice(): Either = Either.catch { grpc.updateDevice(Empty.getDefaultInstance()) } .mapEmpty() + .onLeft { Logger.e("Update device error", it) } .mapLeft { DeviceUpdateError(it) } suspend fun getDeviceList(token: AccountNumber): Either> = Either.catch { grpc.listDevices(StringValue.of(token.value)) } .map { it.devicesList.map(ManagementInterface.Device::toDomain) } + .onLeft { Logger.e("Get device list error", it) } .mapLeft { GetDeviceListError.Unknown(it) } suspend fun removeDevice( @@ -271,18 +274,22 @@ class ManagementService( ) } .mapEmpty() + .onLeft { Logger.e("Remove device error", it) } .mapLeft { DeleteDeviceError.Unknown(it) } suspend fun connect(): Either = Either.catch { grpc.connectTunnel(Empty.getDefaultInstance()).value } + .onLeft { Logger.e("Connect error", it) } .mapLeft(ConnectError::Unknown) suspend fun disconnect(): Either = Either.catch { grpc.disconnectTunnel(Empty.getDefaultInstance()).value } + .onLeft { Logger.e("Disconnect error", it) } .mapLeft(ConnectError::Unknown) suspend fun reconnect(): Either = Either.catch { grpc.reconnectTunnel(Empty.getDefaultInstance()).value } + .onLeft { Logger.e("Reconnect error", it) } .mapLeft(ConnectError::Unknown) private suspend fun getTunnelState(): ModelTunnelState = @@ -301,6 +308,7 @@ class ManagementService( // will get 404 until the api have been published, thus we need to ignore error downstream. private suspend fun getVersionInfo(): Either = Either.catch { grpc.getVersionInfo(Empty.getDefaultInstance()).toDomain() } + .onLeft { Logger.e("Get version info error", it) } .mapLeft { GetVersionInfoError.Unknown(it) } private suspend fun getCurrentApiAccessMethod(): ApiAccessMethodSetting = @@ -308,6 +316,7 @@ class ManagementService( suspend fun logoutAccount(): Either = Either.catch { grpc.logoutAccount(Empty.getDefaultInstance()) } + .onLeft { Logger.e("Logout account error", it) } .mapLeft(LogoutAccountError::Unknown) .mapEmpty() @@ -319,13 +328,17 @@ class ManagementService( Status.Code.RESOURCE_EXHAUSTED -> LoginAccountError.MaxDevicesReached(accountNumber) Status.Code.UNAVAILABLE -> LoginAccountError.RpcError - else -> LoginAccountError.Unknown(it) + else -> { + Logger.e("Unknown login account error", it) + LoginAccountError.Unknown(it) + } } } .mapEmpty() suspend fun clearAccountHistory(): Either = Either.catch { grpc.clearAccountHistory(Empty.getDefaultInstance()) } + .onLeft { Logger.e("Clear account history error", it) } .mapLeft(ClearAccountHistoryError::Unknown) .mapEmpty() @@ -338,6 +351,7 @@ class ManagementService( null } } + .onLeft { Logger.e("Get account history error", it) } .mapLeft(GetAccountHistoryError::Unknown) private suspend fun getInitialServiceState() { @@ -357,6 +371,7 @@ class ManagementService( accountNumber: AccountNumber ): Either = Either.catch { grpc.getAccountData(StringValue.of(accountNumber.value)).toDomain() } + .onLeft { Logger.e("Get account data error", it) } .mapLeft(GetAccountDataError::Unknown) suspend fun createAccount(): Either = @@ -364,10 +379,12 @@ class ManagementService( val accountNumberStringValue = grpc.createNewAccount(Empty.getDefaultInstance()) AccountNumber(accountNumberStringValue.value) } + .onLeft { Logger.e("Create account error", it) } .mapLeft(CreateAccountError::Unknown) suspend fun setDnsOptions(dnsOptions: ModelDnsOptions): Either = Either.catch { grpc.setDnsOptions(dnsOptions.fromDomain()) } + .onLeft { Logger.e("Set dns options error", it) } .mapLeft(SetDnsOptionsError::Unknown) .mapEmpty() @@ -377,6 +394,7 @@ class ManagementService( val updated = DnsOptions.state.set(currentDnsOptions, dnsState) grpc.setDnsOptions(updated.fromDomain()) } + .onLeft { Logger.e("Set dns state error", it) } .mapLeft(SetDnsOptionsError::Unknown) .mapEmpty() @@ -390,6 +408,7 @@ class ManagementService( grpc.setDnsOptions(updatedDnsOptions.fromDomain()) } + .onLeft { Logger.e("Set custom dns error", it) } .mapLeft(SetDnsOptionsError::Unknown) .mapEmpty() @@ -401,6 +420,7 @@ class ManagementService( grpc.setDnsOptions(updatedDnsOptions.fromDomain()) updatedDnsOptions.customOptions.addresses.lastIndex } + .onLeft { Logger.e("Add custom dns error", it) } .mapLeft(SetDnsOptionsError::Unknown) suspend fun deleteCustomDns(index: Int): Either = @@ -414,16 +434,19 @@ class ManagementService( } grpc.setDnsOptions(updatedDnsOptions.fromDomain()) } + .onLeft { Logger.e("Delete custom dns error", it) } .mapLeft(SetDnsOptionsError::Unknown) .mapEmpty() suspend fun setWireguardMtu(value: Int): Either = Either.catch { grpc.setWireguardMtu(UInt32Value.of(value)) } + .onLeft { Logger.e("Set wireguard mtu error", it) } .mapLeft(SetWireguardMtuError::Unknown) .mapEmpty() suspend fun resetWireguardMtu(): Either = Either.catch { grpc.setWireguardMtu(UInt32Value.newBuilder().clearValue().build()) } + .onLeft { Logger.e("Reset wireguard mtu error", it) } .mapLeft(SetWireguardMtuError::Unknown) .mapEmpty() @@ -431,6 +454,7 @@ class ManagementService( value: ModelQuantumResistantState ): Either = Either.catch { grpc.setQuantumResistantTunnel(value.toDomain()) } + .onLeft { Logger.e("Set wireguard quantum resistant error", it) } .mapLeft(SetWireguardQuantumResistantError::Unknown) .mapEmpty() @@ -446,6 +470,7 @@ class ManagementService( } grpc.setObfuscationSettings(updatedObfuscationSettings.fromDomain()) } + .onLeft { Logger.e("Set obfuscation error", it) } .mapLeft(SetObfuscationOptionsError::Unknown) .mapEmpty() @@ -459,16 +484,19 @@ class ManagementService( } grpc.setObfuscationSettings(updatedSettings.fromDomain()) } + .onLeft { Logger.e("Set obfuscation port error", it) } .mapLeft(SetObfuscationOptionsError::Unknown) .mapEmpty() suspend fun setAutoConnect(isEnabled: Boolean): Either = Either.catch { grpc.setAutoConnect(BoolValue.of(isEnabled)) } + .onLeft { Logger.e("Set auto connect error", it) } .mapLeft(SetAutoConnectError::Unknown) .mapEmpty() suspend fun setAllowLan(allow: Boolean): Either = Either.catch { grpc.setAllowLan(BoolValue.of(allow)) } + .onLeft { Logger.e("Set allow lan error", it) } .mapLeft(SetAllowLanError::Unknown) .mapEmpty() @@ -482,6 +510,7 @@ class ManagementService( ) grpc.setRelaySettings(updatedRelaySettings.fromDomain()) } + .onLeft { Logger.e("Set relay location error", it) } .mapLeft(SetRelayLocationError::Unknown) .mapEmpty() @@ -493,7 +522,10 @@ class ManagementService( .mapLeftStatus { when (it.status.code) { Status.Code.ALREADY_EXISTS -> CustomListAlreadyExists - else -> UnknownCustomListError(it) + else -> { + Logger.e("Unknown create custom list error", it) + UnknownCustomListError(it) + } } } @@ -502,18 +534,23 @@ class ManagementService( .mapLeftStatus { when (it.status.code) { Status.Code.ALREADY_EXISTS -> NameAlreadyExists(customList.name) - else -> UnknownCustomListError(it) + else -> { + Logger.e("Unknown update custom list error", it) + UnknownCustomListError(it) + } } } .mapEmpty() suspend fun deleteCustomList(id: CustomListId): Either = Either.catch { grpc.deleteCustomList(StringValue.of(id.value)) } + .onLeft { Logger.e("Delete custom list error", it) } .mapLeft(::UnknownCustomListError) .mapEmpty() suspend fun clearAllRelayOverrides(): Either = Either.catch { grpc.clearAllRelayOverrides(Empty.getDefaultInstance()) } + .onLeft { Logger.e("Clear all relay overrides error", it) } .mapLeft(ClearAllOverridesError::Unknown) .mapEmpty() @@ -523,7 +560,10 @@ class ManagementService( when (it.status.code) { // Currently we only get invalid argument errors from daemon via gRPC Status.Code.INVALID_ARGUMENT -> SettingsPatchError.ParsePatch - else -> SettingsPatchError.ApplyPatch + else -> { + Logger.e("Unknown apply settings patch error", it) + SettingsPatchError.ApplyPatch + } } } .mapEmpty() @@ -537,6 +577,7 @@ class ManagementService( RelaySettings.relayConstraints.wireguardConstraints.set(relaySettings, value) grpc.setRelaySettings(updated.fromDomain()) } + .onLeft { Logger.e("Set wireguard constraints error", it) } .mapLeft(SetWireguardConstraintsError::Unknown) .mapEmpty() @@ -555,6 +596,7 @@ class ManagementService( } grpc.setRelaySettings(updated.fromDomain()) } + .onLeft { Logger.e("Set ownership and providers error", it) } .mapLeft(SetWireguardConstraintsError::Unknown) .mapEmpty() @@ -566,6 +608,7 @@ class ManagementService( val updated = RelaySettings.relayConstraints.ownership.set(relaySettings, ownership) grpc.setRelaySettings(updated.fromDomain()) } + .onLeft { Logger.e("Set ownership error", it) } .mapLeft(SetWireguardConstraintsError::Unknown) .mapEmpty() @@ -578,6 +621,7 @@ class ManagementService( RelaySettings.relayConstraints.providers.set(relaySettings, providersConstraint) grpc.setRelaySettings(updated.fromDomain()) } + .onLeft { Logger.e("Set providers error", it) } .mapLeft(SetWireguardConstraintsError::Unknown) .mapEmpty() @@ -590,26 +634,33 @@ class ManagementService( Status.Code.ALREADY_EXISTS, Status.Code.RESOURCE_EXHAUSTED -> RedeemVoucherError.VoucherAlreadyUsed Status.Code.UNAVAILABLE -> RedeemVoucherError.RpcError - else -> RedeemVoucherError.Unknown(it) + else -> { + Logger.e("Unknown submit voucher error", it) + RedeemVoucherError.Unknown(it) + } } } suspend fun initializePlayPurchase(): Either = Either.catch { grpc.initPlayPurchase(Empty.getDefaultInstance()).toDomain() } + .onLeft { Logger.e("Initialize play purchase error", it) } .mapLeft { PlayPurchaseInitError.OtherError } suspend fun verifyPlayPurchase(purchase: PlayPurchase): Either = Either.catch { grpc.verifyPlayPurchase(purchase.fromDomain()) } + .onLeft { Logger.e("Verify play purchase error", it) } .mapLeft { PlayPurchaseVerifyError.OtherError } .mapEmpty() suspend fun addSplitTunnelingApp(app: AppId): Either = Either.catch { grpc.addSplitTunnelApp(StringValue.of(app.value)) } + .onLeft { Logger.e("Add split tunneling app error", it) } .mapLeft(AddSplitTunnelingAppError::Unknown) .mapEmpty() suspend fun removeSplitTunnelingApp(app: AppId): Either = Either.catch { grpc.removeSplitTunnelApp(StringValue.of(app.value)) } + .onLeft { Logger.e("Remove split tunneling app error", it) } .mapLeft(RemoveSplitTunnelingAppError::Unknown) .mapEmpty() @@ -617,17 +668,20 @@ class ManagementService( enabled: Boolean ): Either = Either.catch { grpc.setSplitTunnelState(BoolValue.of(enabled)) } + .onLeft { Logger.e("Set split tunneling state error", it) } .mapLeft(RemoveSplitTunnelingAppError::Unknown) .mapEmpty() suspend fun getWebsiteAuthToken(): Either = Either.catch { grpc.getWwwAuthToken(Empty.getDefaultInstance()) } + .onLeft { Logger.e("Get website auth token error", it) } .map { WebsiteAuthToken.fromString(it.value) } suspend fun addApiAccessMethod( newAccessMethodSetting: NewAccessMethodSetting ): Either = Either.catch { grpc.addApiAccessMethod(newAccessMethodSetting.fromDomain()) } + .onLeft { Logger.e("Add api access method error", it) } .mapLeft(AddApiAccessMethodError::Unknown) .map { ApiAccessMethodId.fromString(it.value) } @@ -635,6 +689,7 @@ class ManagementService( apiAccessMethodId: ApiAccessMethodId ): Either = Either.catch { grpc.removeApiAccessMethod(apiAccessMethodId.fromDomain()) } + .onLeft { Logger.e("Remove api access method error", it) } .mapLeft(RemoveApiAccessMethodError::Unknown) .mapEmpty() @@ -642,6 +697,7 @@ class ManagementService( apiAccessMethodId: ApiAccessMethodId ): Either = Either.catch { grpc.setApiAccessMethod(apiAccessMethodId.fromDomain()) } + .onLeft { Logger.e("Set api access method error", it) } .mapLeft(SetApiAccessMethodError::Unknown) .mapEmpty() @@ -649,6 +705,7 @@ class ManagementService( apiAccessMethodSetting: ApiAccessMethodSetting ): Either = Either.catch { grpc.updateApiAccessMethod(apiAccessMethodSetting.fromDomain()) } + .onLeft { Logger.e("Update api access method error", it) } .mapLeft(::UnknownApiAccessMethodError) .mapEmpty() @@ -656,6 +713,7 @@ class ManagementService( customProxy: ApiAccessMethod.CustomProxy ): Either = Either.catch { grpc.testCustomApiAccessMethod(customProxy.fromDomain()) } + .onLeft { Logger.e("test custom api access method error", it) } .mapLeftStatus { TestApiAccessMethodError.Grpc } .map { result -> either { ensure(result.value) { TestApiAccessMethodError.CouldNotAccess } } @@ -665,6 +723,7 @@ class ManagementService( apiAccessMethodId: ApiAccessMethodId ): Either = Either.catch { grpc.testApiAccessMethodById(apiAccessMethodId.fromDomain()) } + .onLeft { Logger.e("test api access method error", it) } .mapLeftStatus { TestApiAccessMethodError.Grpc } .map { result -> either { ensure(result.value) { TestApiAccessMethodError.CouldNotAccess } }