invertase / invertase/react-native-apple-authentication
Android: signIn() rejects with generic EUNSPECIFIED instead of E_SIGNIN_CANCELLED_ERROR / E_NOT_CONFIGURED_ERROR
- Dominant language
- JavaScript
- Stars
- 1.7k
- Forks
- 236
- PR merge metrics
- No merged PRs in 30d
Description
### Description
On Android, `appleAuthAndroid.signIn()` almost always rejects with the generic code `EUNSPECIFIED` instead of one of the library's defined error codes (`E_NOT_CONFIGURED_ERROR`, `E_SIGNIN_CANCELLED_ERROR`), which makes it impossible for consumers to distinguish user cancellation from real configuration/signin failures in logs/analytics.
`EUNSPECIFIED` is React Native's own bridge default error code, assigned by `PromiseImpl` whenever native code calls `promise.reject(...)` without an explicit code argument. In `AppleAuthenticationAndroidModule.java`, most `reject` call sites use the single-argument overload, which drops the code:
https://github.com/invertase/react-native-apple-authentication/blob/main/android/src/main/java/com/RNAppleAuthentication/AppleAuthenticationAndroidModule.java
```java
// signIn(), not configured — code is dropped
promise.reject(E_NOT_CONFIGURED_ERROR); // L167
promise.reject(E_NOT_CONFIGURED_ERROR); // L173
// onSignInWithAppleCancel() — user cancellation, code is dropped
promise.reject(E_SIGNIN_CANCELLED_ERROR); // L224
// activity not found — code is dropped
promise.reject(new RuntimeException("Activity is not found")); // L238
```
Only one call site does this correctly:
```java
// onSignInWithAppleFailure() — code is preserved
promise.reject(E_SIGNIN_FAILED_ERROR, error); // L219
```
Since cancellation (`onSignInWithAppleCancel`) is the single most common non-success outcome of the Android webview flow, in practice the vast majority of rejections surface to JS as `EUNSPECIFIED` rather than `E_SIGNIN_CANCELLED_ERROR`. This means apps can't tell "user backed out of the Apple webview" apart from "signIn is misconfigured" or "no Activity available" from the rejected error alone.
I checked and this doesn't appear to be fixed as of the latest release (`2.5.1`) or on `main` — confirmed by diffing `2.4.1...2.5.1` (only unrelated `fullScreen` changes touch this file) and reading the current `main` source directly.
### Steps to reproduce
1. On Android, call `appleAuthAndroid.configure(...)` then `appleAuthAndroid.signIn()`.
2. Dismiss/cancel the Apple sign-in webview dialog before completing.
3. The returned/rejected error has `code === 'EUNSPECIFIED'` instead of `'E_SIGNIN_CANCELLED_ERROR'`.
### Expected behavior
`promise.reject(...)` calls in `AppleAuthenticationAndroidModule.java` should use the two-argument overload (`promise.reject(code, message)` or `promise.reject(code, throwable)`) everywhere, so the code constants already defined at the top of the file (`E_NOT_CONFIGURED_ERROR`, `E_SIGNIN_CANCELLED_ERROR`) are actually surfaced to JS, matching `E_SIGNIN_FAILED_ERROR`'s existing correct usage.
### Environment
- `@invertase/react-native-apple-authentication`: 2.4.1 (confirmed still present on 2.5.1 / main)
- Platform: Android
- React Native (bridge, not exclusive to any specific RN version — this is a generic `Promise.reject` overload issue)
Happy to submit a PR with this fix if useful.
Contributor guide
No contributing guide indexed for this repository
Research direction
Read android/src/main/java/com/RNAppleAuthentication/AppleAuthenticationAndroidModule.java and inspect the listed promise.reject call sites alongside the existing E_SIGNIN_FAILED_ERROR usage. Reproduce the cancellation flow by configuring Apple sign-in and dismissing the Android webview, then verify the rejected JavaScript errors expose the defined configuration and cancellation codes through explicit overloads.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, react-native
- Domain
- authentication, mobile
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100