Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set default values on ProUser data class #1116

Merged
merged 13 commits into from
Jul 4, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import android.content.Context
import android.content.res.Resources
import android.os.Build
import io.lantern.model.Vpn
import org.getlantern.lantern.util.PlansUtil
import org.getlantern.mobilesdk.Logger
import org.getlantern.mobilesdk.model.SessionManager
import org.joda.time.LocalDateTime
Expand Down Expand Up @@ -308,11 +307,11 @@ class LanternSessionManager(application: Application) : SessionManager(applicati

fun storeUserData(user: ProUser) {
Logger.debug(TAG, "Storing user data $user")
if (!user.email.isNullOrEmpty()) {
if (user.email.isNotEmpty()) {
setEmail(user.email)
}

if (!user.code.isNullOrEmpty()) {
if (user.code.isNotEmpty()) {
setCode(user.code)
}

Expand All @@ -324,14 +323,16 @@ class LanternSessionManager(application: Application) : SessionManager(applicati
setExpired(user.isExpired)
setIsProUser(user.isProUser)

val devices = Vpn.Devices.newBuilder().addAllDevices(
user.devices.map {
Vpn.Device.newBuilder().setId(it.id)
.setName(it.name).setCreated(it.created).build()
},
).build()
db.mutate { tx ->
tx.put(DEVICES, devices)
if (user.devices.isNotEmpty()) {
atavism marked this conversation as resolved.
Show resolved Hide resolved
val devices = Vpn.Devices.newBuilder().addAllDevices(
user.devices.map {
Vpn.Device.newBuilder().setId(it.id)
.setName(it.name).setCreated(it.created).build()
},
).build()
db.mutate { tx ->
tx.put(DEVICES, devices)
}
}

if (user.isProUser) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ data class ProUser(
val locale: String = "",
val subscription: String = "",
val expiration: Long = 0,
val devices: List<Device> = mutableListOf<Device>(),
val devices: List<Device> = mutableListOf(),
var userLevel: String = "",
) {
private fun isUserStatus(status: String) = userStatus == status
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package org.getlantern.lantern.model

import com.google.gson.Gson
import com.google.gson.JsonObject
import com.google.gson.JsonParser
import com.google.gson.reflect.TypeToken
import kotlinx.serialization.SerializationException
import okhttp3.CacheControl
import okhttp3.Call
import okhttp3.Callback
Expand All @@ -18,7 +17,6 @@ import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response
import org.getlantern.lantern.LanternApp
import org.getlantern.lantern.service.LanternService
import org.getlantern.lantern.util.JsonUtil
import org.getlantern.lantern.util.PlansUtil
import org.getlantern.mobilesdk.Logger
Expand Down Expand Up @@ -93,9 +91,27 @@ open class LanternHttpClient : HttpClient() {
) {
Logger.debug(TAG, "JSON response" + result.toString())
result?.let {
val user = JsonUtil.fromJson<ProUser>(result.toString())
Logger.debug(TAG, "User ID is ${user.userId}")
cb.onSuccess(response!!, user)
try {
val user = JsonUtil.fromJson<ProUser>(result.toString())
Logger.debug(TAG, "User ID is ${user.userId}")
cb.onSuccess(response!!, user)
} catch (e: SerializationException) {
// If for some reason we get error return user with basic string
Logger.error(TAG, "Unable to parse user from JSON", e)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I found that is you pass devices as null then you still crash, So I added this, so even if we get an exception we catch it and then return some basic details, So at least the app does not crash.

Copy link
Contributor Author

@atavism atavism Jul 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To test this, I set devices to null in the user data JSON response, and another exception is thrown in the catch block (it looks like the email is missing):

07-04 07:21:42.640  1501  1790 E AndroidRuntime: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.google.gson.JsonElement.getAsString()' on a null object reference
07-04 07:21:42.640  1501  1790 E AndroidRuntime: 	at org.getlantern.lantern.model.LanternHttpClient$userData$1.onSuccess(LanternHttpClient.kt:104)
07-04 07:21:42.640  1501  1790 E AndroidRuntime: 	at org.getlantern.lantern.model.LanternHttpClient$proRequest$1.onResponse(LanternHttpClient.kt:321)
07-04 07:21:42.640  1501  1790 E AndroidRuntime: 	at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:519)
07-04 07:21:42.640  1501  1790 E AndroidRuntime: 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
07-04 07:21:42.640  1501  1790 E AndroidRuntime: 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
07-04 07:21:42.640  1501  1790 E AndroidRuntime: 	at java.lang.Thread.run(Thread.java:1012)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jigar-f What do you think of this change to add and make use of a tryParseJson utility method that catches and logs any exception? #1117

val userId = result.get("userId").asLong
val token = result.get("token").asString
val referral = result.get("referral").asString
val email = result.get("email").asString
val userStatus = result.get("userStatus").asString
val userLevel = result.get("userLevel").asString
val user = ProUser(
userId, token, referral, email, userStatus, "", "en_us", "", 0L,
mutableListOf(), userLevel
)
cb.onSuccess(response!!, user)

}

}
}
},
Expand Down
Loading