adaptyteam / AdaptySDK-React-Native

React Native SDK for growing in-app subscriptions
https://docs.adapty.io/docs/quickstart
MIT License
122 stars 12 forks source link

JSON Parse error: Unexpected token: P #44

Closed ildfreelancer closed 1 year ago

ildfreelancer commented 1 year ago

Context:

After upgrading to latest version, I got this issue from Sentry, but I don't know how to fix:

node_modules/react-native-adapty/lib/dist/internal/bridgeError.js in BridgeError at line 10:40

var error_1 = require("../types/error");
var BridgeError = /** @class */ (function (_super) {
    tslib_1.__extends(BridgeError, _super);
    function BridgeError(data) {
        var _this = this;
        var errNative = JSON.parse(data['message']);
        var adaptyCode = errNative['adapty_code'];
        var detail = errNative['detail'];
        var message = errNative['message'];
        _this = _super.call(this, message || detail || adaptyCode) || this;
        _this.adaptyCode = adaptyCode;

it threw the issue here:

var errNative = JSON.parse(data['message']);
ildfreelancer commented 1 year ago

On old version for ios user, Unknown Adapty Error

I got this

node_modules/react-native-adapty/lib/dist/sdk/error.js in horoscopeNotification at line 9:28

var tslib_1 = require("tslib");
var AdaptyError = /** @class */ (function (_super) {
    tslib_1.__extends(AdaptyError, _super);
    function AdaptyError(_a) {
        var adaptyCode = _a.adaptyCode, localizedDescription = _a.localizedDescription, code = _a.code;
        var _this = _super.call(this, localizedDescription || 'Unknown Adapty Error') || this;
        _this.adaptyCode = adaptyCode;
        _this.localizedDescription = localizedDescription || 'Unknown Adapty Error';
        _this.code = code;
        return _this;
    }

Issue here:

        var _this = _super.call(this, localizedDescription || 'Unknown Adapty Error') || this;
divanc commented 1 year ago

Hey! Sorry for a late reply! It seems you have an error without a message to be parsed (which is not ok). Can you provide any more info what do you do to get this?

If it is right from the start, could it be that you haven't fetched new native lib via gradle sync?

ildfreelancer commented 1 year ago

@divanc Thanks for replying, currently I cannot reproduce it from my devices, but we found bunch of this errors from Sentry. We are trying to add verbose log to see what we can collect.

divanc commented 1 year ago

I wasn't able to get this error today on my example app. I'm looking forward to see your logs!

ildfreelancer commented 1 year ago

@divanc Unfortnately, even I added verbose log, but I cannot log the issue from Adapty SDK

We still get around 1300 events affected over 800 users

Can you suggest any way to detect the errors or event collect log from your Adapty SDK?

image
divanc commented 1 year ago

Excuse me, I had to be offline for a couple of days and now digging all the requests for me.

Does the number still grow? In v2.3.4 I've handled unknown errors constructors this way: error.localizedDescription would have "Unknown error. JSON: /* JSON string of the error */". If you don't want to expose a clumsy text like this to an end user, you can handle these errors, they have error.adaptyCode == 'unknown'.


To explain the previous errors origin, I've found several occurrences on Android:

1. When argument was not passed to Android bridge

If you have TypeScript, that should not be the case. If you don't have argument validation, you should check all functions to have valid arguments types (updateAttribution arguments order has changed in v2, it is a good candidate)

2. When you call a not implemented function

It should not be the case, if you do not directly call ReactNative.NativeModules, Adapty is not designed to be used like that. I believe, this is not your case :)

I hope this helps!

ildfreelancer commented 1 year ago

@divanc Thanks for updating on this issue, we will roll out a new build with the latest version of react-native-adapty 2.3.4 today. We will let you know, so I think we can keep this issue option for 1 week, is it okay?

Note: we are using Typescript, we don't use updateAttribution, and we don't call NativeModules, just use methods on examples on documentation.

ildfreelancer commented 1 year ago

@divanc we are using updateProfile,

image

but I think it is ok?

divanc commented 1 year ago

We can leave this issue for the time certainly, I just mark them, so I know, which ones I think does not require a lot of work anymore

About updateProfile - I would check everything and answer you in several hours. About typescript - I should probably add serialization type checker, just to be sure. Also these errors should contain more comprehensive descriptions now

divanc commented 1 year ago

Sending both undefined and null should be equally fine.

ildfreelancer commented 1 year ago

@divanc I think I found where the issue comes from

2023-02-22 10:33:26.886 13074-13284 Adapty_v2.3.1 V VERBOSE: getPaywall(id = premium) 2023-02-22 10:33:26.890 13074-13284 Adapty_v2.3.1 E ERROR: Play Market request failed: Billing service unavailable on device. 2023-02-22 10:33:26.894 13074-13225 ReactNativeJS W [SyntaxError: JSON Parse error: Unexpected token: P]

I am thinking some devices of my users don't support the Billing service, which makes adapty cannot get Paywall. I am checking

SyntaxError: JSON Parse error: Unexpected token: P]

from our logic or adapty js side.

ildfreelancer commented 1 year ago

@divanc I think this edge case is not handled properly on SDK, native side, I think

SyntaxError: JSON Parse error: Unexpected token: C
    at parse (native)

this should be from native, not from our JS handle

divanc commented 1 year ago

JSON Parse Error is the one that is thrown from JS's JSON.parse. I thought I've handled all of these in v2.3.4. Going to browse all the code today.

divanc commented 1 year ago

Hey, @ildfreelancer! In v2.3.6 I resolved all the Android serialization problems. They should not occur anymore

It should only raise the error you have found to JS layer:

2023-02-22 10:33:26.886 13074-13284 Adapty_v2.3.1 V VERBOSE: getPaywall(id = premium) 2023-02-22 10:33:26.890 13074-13284 Adapty_v2.3.1 E ERROR: Play Market request failed: Billing service unavailable on device.

About this error: do you get it on an emulator with Play Market? Are you logged in to your Google account? Maybe this device does not have a Play Market at all?

ildfreelancer commented 1 year ago

@divanc great, let me try it

About this error: do you get it on an emulator with Play Market? Are you logged in to your Google account? Maybe this device does not have a Play Market at all? => correct, this error comes in due to unavailable Play Store service. You can ignore it. => But I think this is an edge case leading to the issue parse error we got (or maybe different reason) Because we got the report from sentry in production mode.

alright commented 1 year ago

Hi everyone, I am having the same issue on Android: SyntaxError: Unexpected token C in JSON at position 0 at JSON.parse (<anonymous>) at new BridgeError

I am running in an emulator, have Play Market installed, logged in with proper testing account, npm package v. 2.3.6

divanc commented 1 year ago

Hey, @alright! I hope peace finds you πŸ‡ΊπŸ‡¦! Can you check the logs inside Android Studio (if that is how you run)? It should display a proper error

divanc commented 1 year ago

Also a little but more description β€” does it appear after firing some action?

alright commented 1 year ago

Thank you!

I am trying to purchase a subscription. This is what I get in Android Studio:

2023-02-27 12:31:28.567 12855-14356/com.mobile V/Adapty_v2.3.1: VERBOSE: GET https://api.adapty.io/api/v1/sdk/analytics/profiles/.../
2023-02-27 12:31:28.584 12855-14355/com.mobile D/TrafficStats: tagSocket(170) with statsTag=0xffffffff, statsUid=-1
2023-02-27 12:31:28.613 12855-12855/com.mobile E/unknown:ReactModalHost: Creating new dialog from context: com.mobile.MainActivity@bfca31d@201106205
2023-02-27 12:31:28.621 563-2147/? D/CoreBackPreview: Window{edb2476 u0 com.mobile/com.mobile.MainActivity}: Setting back callback OnBackInvokedCallbackInfo{mCallback=android.window.IOnBackInvokedCallback$Stub$Proxy@e5906e4, mPriority=0}
2023-02-27 12:31:28.639 387-493/? D/goldfish-address-space: claimShared: Ask to claim region [0x1f55cc000 0x1f5f34000]
2023-02-27 12:31:28.642 387-493/? D/goldfish-address-space: claimShared: Ask to claim region [0x1f5f34000 0x1f689c000]
2023-02-27 12:31:28.643 387-493/? D/goldfish-address-space: claimShared: Ask to claim region [0x1f689c000 0x1f7204000]
2023-02-27 12:31:28.652 12855-12932/com.mobile W/Parcel: Expecting binder but got null!
2023-02-27 12:31:28.655 853-931/? D/EGL_emulation: app_time_stats: avg=28633.76ms min=28633.76ms max=28633.76ms count=1
2023-02-27 12:31:28.662 12855-12855/com.mobile E/unknown:ReactModalHost: Updating existing dialog with context: com.mobile.MainActivity@bfca31d@201106205
2023-02-27 12:31:28.795 12855-14356/com.mobile V/Adapty_v2.3.1: VERBOSE: (chunk 1) Request is successful. https://api.adapty.io/api/v1/sdk/analytics/profiles/.../ Response: ...
2023-02-27 12:31:28.816 8530-8530/? I/GoogleInputMethodService: GoogleInputMethodService.onFinishInput():3220 
2023-02-27 12:31:28.819 8530-8530/? I/GoogleInputMethodService: GoogleInputMethodService.updateDeviceLockedStatus():2114 repeatCheckTimes = 0, unlocked = true
2023-02-27 12:31:28.819 8530-8530/? I/GoogleInputMethodService: GoogleInputMethodService.onStartInput():1919 onStartInput(EditorInfo{inputType=0x0(NULL) imeOptions=0x0 privateImeOptions=null actionName=UNSPECIFIED actionLabel=null actionId=0 initialSelStart=-1 initialSelEnd=-1 initialCapsMode=0x0 hintText=null label=null packageName=com.mobile fieldId=-1 fieldName=null extras=null}, false)
2023-02-27 12:31:28.819 8530-8530/? I/GoogleInputMethodService: GoogleInputMethodService.updateDeviceLockedStatus():2114 repeatCheckTimes = 2, unlocked = true
2023-02-27 12:31:28.840 12855-12989/com.mobile E/ReactNativeJS: { error: { [SyntaxError: JSON Parse error: Unexpected identifier "n"] line: 1102, column: 168, sourceURL: 'index.android.bundle' } }
2023-02-27 12:31:28.847 12855-12990/com.mobile E/unknown:ReactNative: console.error: {"error":{"line":1102,"column":168,"sourceURL":"index.android.bundle"}}, stack:
    construct@-1
    construct@-1
    o@169:330
    construct@-1
    <unknown>@168:437
    s@168:637
    f@168:1781
    <unknown>@2454:3892
    p@186:1352
    <unknown>@186:1101
    p@186:1352
    o@186:1767
    <unknown>@186:1949
    u@181:156
    <unknown>@181:865
    <unknown>@189:1661
    k@189:497
    w@189:887
    callReactNativeMicrotasks@189:3054
    value@146:2867
    <unknown>@146:959
    value@146:2503
    value@146:918
    value@-1
2023-02-27 12:31:28.893 563-2147/? D/CoreBackPreview: Window{edb2476 u0 com.mobile/com.mobile.MainActivity}: Setting back callback null
divanc commented 1 year ago

Can you guys try v2.3.10 with verbose? It offers a lot of nice logs in JS output

alright commented 1 year ago

Tried v2.3.10. It seems the issue is with handling long response, divided into chunks.

V/Adapty_v2.3.3: VERBOSE: getProfile()
V/Adapty_v2.3.3: VERBOSE: GET https://api.adapty.io/api/v1/sdk/analytics/profiles/c4965fff-16a3-4aa0-a9bf-9bb6a773afdd/
D/EGL_emulation: app_time_stats: avg=14666.98ms min=62.34ms max=29271.62ms count=2
V/Adapty_v2.3.3: VERBOSE: (chunk 1) Request is successful. https://api.adapty.io/api/v1/sdk/analytics/profiles/c4965fff-16a3-4aa0-a9bf-9bb6a773afdd/ Response: {"data":{"type":"adapty_analytics_profile","id":"c4965fff-16a3-4aa0-a9bf-9bb6a773afdd","attributes":{"app_id":"ba0a3e4d-dfb1-42ea-8b4e-6285c2ba461f","profile_id":"c4965fff-16a3-4aa0-a9bf-9bb6a773afdd","customer_user_id":"a4a32a78-78bb-46b9-baa0-0df7869d8e05","total_revenue_usd":6242.275499999995,"paid_access_levels":{"personal_platinum":{"id":"personal_platinum","is_active":false,"is_lifetime":false,"expires_at":"2023-01-07T08:48:05.000000+0000","starts_at":null,"will_renew":false,"vendor_product_id":"mobile.plan.personal.platinum_yearly","store":"app_store","activated_at":"2022-10-06T12:03:45.000000+0000","renewed_at":"2023-01-07T07:48:05.000000+0000","unsubscribed_at":"2023-01-07T08:48:05.000000+0000","billing_issue_detected_at":null,"is_in_grace_period":false,"active_introductory_offer_type":null,"active_promotional_offer_type":null,"active_promotional_offer_id":null,"cancellation_reason":null,"is_refund":false},"personal_silver":{"id":"personal_silver","is_active":false,"is_lifetime":false,"expires_at":"2022-12-09T12:43:23.000000+0000","starts_at":null,"will_renew":false,"vendor_product_id":"mobile.plan.personal.silver_monthly","store":"app_store","activated_at":"2022-12-09T09:42:02.000000+0000","renewed_at":"2022-12-09T12:38:23.000000+0000","unsubscribed_at":"2022-12-09T12:43:23.000000+0000","billing_issue_detected_at":null,"is_in_grace_period":false,"active_introductory_offer_type":null,"active_promotional_offer_type":null,"active_promotional_offer_id":null,"cancellation_reason":null,"is_refund":false},"personal_gold":{"id":"personal_gold","is_active":false,"is_lifetime":false,"expires_at":"2023-01-19T22:13:02.000000+0000","starts_at":null,"will_renew":false,"vendor_product_id":"mobile.plan.personal.gold_monthly","store":"app_store","activated_at":"2022-10-06T12:03:45.000000+0000","renewed_at":"2023-01-19T22:08:02.000000+0000","unsubscribed_at":"2023-01-19T22:13:02.000000+0000","billing_issue_detected_at":"2023-01-19T22:13:02.000000+0000","is_in_grace_period":false,"active_introductory_offer_type":null,"active_promotional_offer_type":null,"active_promotional_offer_id":null,"cancellation_reason":"voluntarily_cancelled","is_refund":false},"premium":{"id":"premium","is_active":false,"is_lifetime":false,"expires_at":"2022-11-30T23:59:59.999999+0000","starts_at":null,"will_renew":false,"vendor_product_id":"adapty_promotion","store":"adapty","activated_at":"2022-12-08T11:31:03.820072+0000","renewed_at":null,"unsubscribed_at":null,"billing_issue_detected_at":null,"is_in_grace_period":false,"active_introductory_offer_type":null,"active_promotional_offer_type":null,"active_promotional_offer_id":null,"cancellation_reason":null,"is_refund":false},"business_professional":{"id":"business_professional","is_active":false,"is_lifetime":false,"expires_at":"2022-12-09T12:34:32.000000+0000","starts_at":null,"will_renew":false,"vendor_product_id":"mobile.plan.business.professional_yearly","store":"app_store","activated_at":"2022-12-09T09:51:58.000000+0000","renewed_at":"2022-12-09T11:34:32.000000+0000","unsubscribed_at":"2022-12-09T12:34:32.000000+0000","billing_issue_detected_at":"2022-12-09T12:34:32.000000+0000","is_in_grace_period":false,"active_introductory_offer_type":null,"active_promotional_offer_type":null,"active_promotional_offer_id":null,"cancellation_reason":"voluntarily_cancelled","is_refund":false},"business_essentians":{"id":"business_essentians","is_active":false,"is_lifetime":false,"expires_at":"2022-12-09T11:34:32.000000+0000","starts_at":null,"will_renew":false,"vendor_product_id":"mobile.plan.business.essentials_yearly","store":"app_store","activated_at":"2022-12-09T09:51:58.000000+0000","renewed_at":"2022-12-09T10:55:22.000000+0000","unsubscribed_at":"2022-12-09T11:55:22.000000+0000","billing_issue_detected_at":null,"is_in_grace_period":false,"active_introductory_offer_type":null,"active_promotional
V/Adapty_v2.3.3: VERBOSE: (chunk 2) _offer_type":null,"active_promotional_offer_id":null,"cancellation_reason":"upgraded","is_refund":false}},"subscriptions":{"mobile.plan.personal.gold_monthly":{"is_active":false,"is_lifetime":false,"expires_at":"2023-01-19T22:13:02.000000+0000","starts_at":null,"will_renew":false,"vendor_product_id":"mobile.plan.personal.gold_monthly","vendor_transaction_id":"2000000254397340","vendor_original_transaction_id":"2000000171087897","store":"app_store","activated_at":"2022-10-06T12:03:45.000000+0000","renewed_at":"2023-01-19T22:08:02.000000+0000","unsubscribed_at":"2023-01-19T22:13:02.000000+0000","billing_issue_detected_at":null,"is_in_grace_period":false,"active_introductory_offer_type":null,"active_promotional_offer_type":null,"active_promotional_offer_id":null,"cancellation_reason":"voluntarily_cancelled","is_sandbox":true,"is_refund":false},"mobile.plan.personal.silver_monthly":{"is_active":false,"is_lifetime":false,"expires_at":"2022-12-08T16:40:52.000000+0000","starts_at":null,"will_renew":false,"vendor_product_id":"mobile.plan.personal.silver_monthly","vendor_transaction_id":"2000000223143171","vendor_original_transaction_id":"2000000171087897","store":"app_store","activated_at":"2022-10-06T12:03:45.000000+0000","renewed_at":"2022-12-08T16:35:52.000000+0000","unsubscribed_at":"2022-12-08T16:40:52.000000+0000","billing_issue_detected_at":null,"is_in_grace_period":false,"active_introductory_offer_type":null,"active_promotional_offer_type":null,"active_promotional_offer_id":null,"cancellation_reason":null,"is_sandbox":true,"is_refund":false},"mobile.plan.personal.platinum_monthly":{"is_active":false,"is_lifetime":false,"expires_at":"2022-12-09T10:25:39.000000+0000","starts_at":null,"will_renew":false,"vendor_product_id":"mobile.plan.personal.platinum_monthly","vendor_transaction_id":"2000000223766607","vendor_original_transaction_id":"2000000171087897","store":"app_store","activated_at":"2022-10-06T12:03:45.000000+0000","renewed_at":"2022-12-09T10:20:39.000000+0000","unsubscribed_at":"2022-12-09T10:25:39.000000+0000","billing_issue_detected_at":null,"is_in_grace_period":false,"active_introductory_offer_type":null,"active_promotional_offer_type":null,"active_promotional_offer_id":null,"cancellation_reason":null,"is_sandbox":true,"is_refund":false},"mobile.plan.business.professional_yearly":{"is_active":false,"is_lifetime":false,"expires_at":"2022-12-09T03:40:18.000000+0000","starts_at":null,"will_renew":false,"vendor_product_id":"mobile.plan.business.professional_yearly","vendor_transaction_id":"2000000223366004","vendor_original_transaction_id":"2000000223109767","store":"app_store","activated_at":"2022-12-08T15:40:22.000000+0000","renewed_at":"2022-12-09T02:40:18.000000+0000","unsubscribed_at":"2022-12-09T03:40:18.000000+0000","billing_issue_detected_at":null,"is_in_grace_period":false,"active_introductory_offer_type":null,"active_promotional_offer_type":null,"active_promotional_offer_id":null,"cancellation_reason":"voluntarily_cancelled","is_sandbox":true,"is_refund":false},"mobile.plan.business.essentials_yearly":{"is_active":false,"is_lifetime":false,"expires_at":"2022-12-09T11:34:32.000000+0000","starts_at":null,"will_renew":false,"vendor_product_id":"mobile.plan.business.essentials_yearly","vendor_transaction_id":"2000000223804603","vendor_original_transaction_id":"2000000223728240","store":"app_store","activated_at":"2022-12-09T09:51:58.000000+0000","renewed_at":"2022-12-09T10:55:22.000000+0000","unsubscribed_at":"2022-12-09T11:55:22.000000+0000","billing_issue_detected_at":null,"is_in_grace_period":false,"active_introductory_offer_type":null,"active_promotional_offer_type":null,"active_promotional_offer_id":null,"cancellation_reason":"upgraded","is_sandbox":true,"is_refund":false},"mobile.plan.personal.platinum_yearly":{"is_active":false,"is_lifetime":false,"expires_at":"2023-01-07T08:48:05.000000+0000","starts_at":null,"will_renew":false,"vendor_product_id":"mobile.plan.personal.platinum_yearly","vendor_transaction_id
V/Adapty_v2.3.3: VERBOSE: (chunk 3) ":"2000000244334476","vendor_original_transaction_id":"2000000171087897","store":"app_store","activated_at":"2022-10-06T12:03:45.000000+0000","renewed_at":"2023-01-07T07:48:05.000000+0000","unsubscribed_at":"2023-01-07T08:48:05.000000+0000","billing_issue_detected_at":null,"is_in_grace_period":false,"active_introductory_offer_type":null,"active_promotional_offer_type":null,"active_promotional_offer_id":null,"cancellation_reason":null,"is_sandbox":true,"is_refund":false}},"non_subscriptions":{"mobile.hotlikes.one":[{"purchase_id":"ff1078cf-ecf1-4a2b-8e19-1a41d920a74a","purchased_at":"2022-12-07T17:19:43.000000+0000","vendor_product_id":"mobile.hotlikes.one","vendor_transaction_id":"2000000222075112","vendor_original_transaction_id":"2000000222075112","store":"app_store","is_one_time":false,"is_sandbox":true,"is_refund":false}]},"custom_attributes":{},"promotional_offer_eligibility":false,"introductory_offer_eligibility":true}}}
E/ReactNativeJS: { error: { [SyntaxError: JSON Parse error: Unexpected identifier "n"] line: 1102, column: 168, sourceURL: 'index.android.bundle' } }
E/unknown:ReactNative: console.error: {"error":{"line":1102,"column":168,"sourceURL":"index.android.bundle"}}, stack:
    construct@-1
    construct@-1
    o@169:330
    construct@-1
    <unknown>@168:437
    s@168:637
    f@168:1781
    <unknown>@2454:3892
    p@186:1352
    <unknown>@186:1101
    p@186:1352
    o@186:1767
    <unknown>@186:1949
    u@181:156
    <unknown>@181:865
    <unknown>@189:1661
    k@189:497
    w@189:887
    callReactNativeMicrotasks@189:3054
    value@146:2867
    <unknown>@146:959
    value@146:2503
    value@146:918
    value@-1
    value@-1
E/unknown:ReactModalHost: Creating new dialog from context: com.mobile.mobile.MainActivity@e2b815c@237732188
divanc commented 1 year ago

Hello again, @alright. Chunking is something to solve logcat's own behavior. It strips longer lines at log basically disappears. It is not that convenient to cut JSON in chunks as it is not readable, when incomplete...

I've tested this object with my tests, which turned out alright. Can you please check JS logs (RN server console)? When verbose, they should provide you with the exact deserialization problem instead of this ambiguous message

divanc commented 1 year ago

@alright, can you please tell, whether problem remains? Also whether you've tried looking into verbose JS logs?

alright commented 1 year ago

Works fine for us on 2.3.13, thank you!