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

NPE empty attributes #2752

Merged
merged 10 commits into from
Jun 22, 2023
Merged

NPE empty attributes #2752

merged 10 commits into from
Jun 22, 2023

Conversation

atorresveiga
Copy link
Contributor

@atorresveiga atorresveiga commented Jun 13, 2023

Closes: woocommerce/woocommerce-android#9160
Closes: woocommerce/woocommerce-android#9162

Description

This PR solves the NPE crash in the app when receiving unexpected values in the attributes field. We previously caught only JsonParseException parsing exceptions, and now we are swallowing all types of exceptions. Now, we return an empty list whenever we fail to parse the product attributes (the same behavior we had before but only for JsonParseException).

Here p1686673876637129-slack-CGPNUU63E, we discussed about the WCProductModel refactor to be able to unit tests the attributes deserialization.

Testing

Check that exceptions deserializing product's attributes don't crash the app

@atorresveiga atorresveiga marked this pull request as ready for review June 16, 2023 13:42
@ThomazFB ThomazFB self-assigned this Jun 21, 2023
Copy link
Contributor

@ThomazFB ThomazFB left a comment

Choose a reason for hiding this comment

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

Tests are good and seem to work just fine! I've left some suggestions regarding how to remove the lint suppressions and keep the same strategy, but nothing blocking!

* Returns the list of products attributes. The function returns an empty list
* when the attributes json deserialization fails.
*/
@Suppress("SwallowedException", "TooGenericExceptionCaught")
Copy link
Contributor

Choose a reason for hiding this comment

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

np: I think you don't need the "SwallowedException" supression here.

@@ -347,7 +352,7 @@ data class WCProductModel(@PrimaryKey @Column private var id: Int = 0) : Identif
)
}
}
} catch (e: JsonParseException) {
} catch (e: Exception) {
Copy link
Contributor

@ThomazFB ThomazFB Jun 21, 2023

Choose a reason for hiding this comment

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

There's a way to refactor this while keeping the generic catch, avoiding the TooGenericExceptionCaught supression, and improve the overall performance of the operation while keeping it idiomatic:

        return kotlin.runCatching {
            Gson().fromJson(attributes, JsonElement::class.java)
                .asJsonArray.asSequence()
                .map { it.asJsonObject }
                .map { json ->
                    ProductAttribute(
                        id = json.getLong("id"),
                        name = json.getString("name") ?: "",
                        variation = json.getBoolean("variation", true),
                        visible = json.getBoolean("visible", true),
                        options = getAttributeOptions(json.getAsJsonArray("options"))
                    )
                }.toList()
        }.fold(
            onSuccess = { it },
            onFailure = { emptyList() }
        )

By using the runCatching, we make sure that every single Throwable coming from that block will trigger the onFailure, allowing us to remove all suppression from the top of the function and making it clear what to do on each scenario through the result folding.

WDYT? Makes sense?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

TIL about kotlin.runCatching, great recommendation @ThomazFB 👍
Fixed here 3a00135

import org.assertj.core.api.Assertions
import org.junit.Test

class WCProductModelTest {
Copy link
Contributor

Choose a reason for hiding this comment

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

Great work adding unit tests!

@ThomazFB
Copy link
Contributor

Thank you for moving forward with my suggestion, @atorresveiga! Looks good!

@ThomazFB ThomazFB merged commit 9f4afdc into trunk Jun 22, 2023
@ThomazFB ThomazFB deleted the issue/9160-npe-empty-attributes branch June 22, 2023 15:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants