Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,26 @@ public void onFailure(AdError adError) {
break;
}

String sdkCodeName = errorCode.name();
String sdkMessage = adError.getMessage();
if (sdkMessage == null) {
sdkMessage = "";
}
String composedMessage =
"Failed to load APS ad (mapped: "
+ code
+ ", SDK: "
+ sdkCodeName
+ ", ordinal: "
+ errorCode.ordinal()
+ ")"
+ (sdkMessage.isEmpty() ? "" : " — " + sdkMessage);

WritableMap userInfoMap = Arguments.createMap();
userInfoMap.putString("code", code);
userInfoMap.putString("message", adError.getMessage());
userInfoMap.putString("message", composedMessage);
userInfoMap.putString("sdkCode", sdkCodeName);
userInfoMap.putInt("rawValue", errorCode.ordinal());

WritableMap payload = Arguments.createMap();
payload.putInt("loaderId", loaderId);
Expand All @@ -116,8 +133,10 @@ public void onFailure(AdError adError) {
// Créer une copie pour promise.reject car userInfoMap est déjà utilisé
WritableMap userInfoCopy = Arguments.createMap();
userInfoCopy.putString("code", code);
userInfoCopy.putString("message", adError.getMessage());
promise.reject(code, adError.getMessage(), userInfoCopy);
userInfoCopy.putString("message", composedMessage);
userInfoCopy.putString("sdkCode", sdkCodeName);
userInfoCopy.putInt("rawValue", errorCode.ordinal());
promise.reject(code, composedMessage, userInfoCopy);
promise = null;
}
}
Expand Down
2 changes: 1 addition & 1 deletion example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"react": "18.3.1",
"react-native": "0.77.3",
"react-native-aps": "link:../",
"react-native-google-mobile-ads": "^14.2.0"
"react-native-google-mobile-ads": "15.8.3"
},
"devDependencies": {
"@babel/core": "^7.25.2",
Expand Down
29 changes: 25 additions & 4 deletions example/src/Banner.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ export default function BannerDemo() {
(error) => {
setApsBidError(error);
setBidComplete(true);
addEvent(`APS bid failed (code: ${error.code})`);
addEvent(
`APS bid failed (${error.formatShortLabel()}) — ${error.message}`
);
}
);

Expand All @@ -70,7 +72,9 @@ export default function BannerDemo() {
: new AdError('unknown', String(error?.message ?? error));
setApsBidError(adError);
setBidComplete(true);
addEvent(`APS bid failed (code: ${adError.code})`);
addEvent(
`APS bid failed (${adError.formatShortLabel()}) — ${adError.message}`
);
});
addEvent('APS bid requested');

Expand Down Expand Up @@ -116,10 +120,15 @@ export default function BannerDemo() {
<Text style={styles.badgeTextSuccess}>Won</Text>
</View>
) : (
<View style={[styles.badge, styles.badgeError]}>
<View style={[styles.badge, styles.badgeError, styles.badgeErrorStack]}>
<Text style={styles.badgeTextError}>
Failed ({apsBidError?.code ?? '?'})
Failed ({apsBidError?.formatShortLabel() ?? '?'})
</Text>
{!!apsBidError?.message && (
<Text style={styles.badgeTextErrorDetail} numberOfLines={3}>
{apsBidError.message}
</Text>
)}
</View>
)}
</View>
Expand Down Expand Up @@ -257,6 +266,18 @@ const styles = StyleSheet.create({
badgeError: {
backgroundColor: '#fef2f2',
},
badgeErrorStack: {
flexDirection: 'column',
alignItems: 'flex-end',
maxWidth: '78%',
gap: 4,
},
badgeTextErrorDetail: {
fontSize: 11,
color: '#b91c1c',
fontWeight: '400',
textAlign: 'right',
},
badgeTextLoading: {
fontSize: 13,
color: '#6366f1',
Expand Down
25 changes: 22 additions & 3 deletions example/src/Interstitial.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ export default function InterstitialDemo() {
.catch((error) => {
if (isAdError(error)) {
setApsBidError(error);
addEvent(`APS bid failed (code: ${error.code})`);
addEvent(
`APS bid failed (${error.formatShortLabel()}) — ${error.message}`
);
}
const interstitial = GAMInterstitialAd.createForAdRequest(
TestIds.GAM_INTERSTITIAL
Expand Down Expand Up @@ -137,10 +139,15 @@ export default function InterstitialDemo() {
<Text style={styles.badgeTextSuccess}>Won</Text>
</View>
) : apsBidError ? (
<View style={[styles.badge, styles.badgeError]}>
<View style={[styles.badge, styles.badgeError, styles.badgeErrorStack]}>
<Text style={styles.badgeTextError}>
Failed ({apsBidError.code})
Failed ({apsBidError.formatShortLabel()})
</Text>
{!!apsBidError.message && (
<Text style={styles.badgeTextErrorDetail} numberOfLines={3}>
{apsBidError.message}
</Text>
)}
</View>
) : (
<View style={[styles.badge, styles.badgeSuccess]}>
Expand Down Expand Up @@ -280,6 +287,18 @@ const styles = StyleSheet.create({
badgeError: {
backgroundColor: '#fef2f2',
},
badgeErrorStack: {
flexDirection: 'column',
alignItems: 'flex-end',
maxWidth: '78%',
gap: 4,
},
badgeTextErrorDetail: {
fontSize: 11,
color: '#b91c1c',
fontWeight: '400',
textAlign: 'right',
},
badgeTextLoading: {
fontSize: 13,
color: '#6366f1',
Expand Down
10 changes: 5 additions & 5 deletions example/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4841,7 +4841,7 @@ __metadata:
react: "npm:18.3.1"
react-native: "npm:0.77.3"
react-native-aps: "link:../"
react-native-google-mobile-ads: "npm:^14.2.0"
react-native-google-mobile-ads: "npm:15.8.3"
typescript: "npm:^5.0.4"
languageName: unknown
linkType: soft
Expand All @@ -4852,9 +4852,9 @@ __metadata:
languageName: node
linkType: soft

"react-native-google-mobile-ads@npm:^14.2.0":
version: 14.11.0
resolution: "react-native-google-mobile-ads@npm:14.11.0"
"react-native-google-mobile-ads@npm:15.8.3":
version: 15.8.3
resolution: "react-native-google-mobile-ads@npm:15.8.3"
dependencies:
"@iabtcf/core": "npm:^1.5.3"
use-deep-compare-effect: "npm:^1.8.1"
Expand All @@ -4863,7 +4863,7 @@ __metadata:
peerDependenciesMeta:
expo:
optional: true
checksum: 10c0/5d424081fc14f1da9d495cdf26109fb0d55c5d1599fb651d5117f36357eab0334e61701557046e1f58b84e4cafa480dcf6ac13071641188950fcdcf10f00e2c4
checksum: 10c0/444adaa3a852a2acbe799802ba5e1b4cf9b94c5ff07c2e2d0a403084a85120060b5426046e613fe90efe92b222949dbbe5dcd38fd4d25cce70d7e46bad9af8c7
languageName: node
linkType: hard

Expand Down
17 changes: 13 additions & 4 deletions ios/RNAPS/RNAPSAdLoaderModule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,19 @@ class RNAPSAdLoaderModule: RCTEventEmitter {
default: // Use simple default to ensure exhaustiveness
code = "unknown"
}
let message = String(format: "Failed to load APS ad with code: %@", code)
var userInfo = Dictionary<String, String>()
userInfo["code"] = code
userInfo["message"] = message
let sdkLabel = String(describing: error)
let message = String(
format: "Failed to load APS ad (mapped: %@, APS: %@, rawValue: %d)",
code,
sdkLabel,
error.rawValue
)
let userInfo: [String: Any] = [
"code": code,
"message": message,
"sdkCode": sdkLabel,
"rawValue": error.rawValue,
]
adLoaderModule.sendEvent(name: RNAPSAdLoaderModule.EVENT_FAILURE, body: [
"loaderId": loaderId,
"userInfo": userInfo
Expand Down
52 changes: 47 additions & 5 deletions src/AdError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,61 @@
* along with Foobar. If not, see <https://www.gnu.org/licenses/>.
*/

export type AdErrorExtras = {
/** Amazon SDK error label (e.g. iOS `String(describing:)`, Android `ErrorCode.name()`). */
sdkCode?: string;
/** Raw / ordinal value from the native SDK when available. */
rawValue?: number;
};

/**
* AdError class
*
* AdError class — normalized `code` from the bridge, plus optional native details for debugging.
*/
export class AdError extends Error {
constructor(readonly code: string, message: string) {
readonly code: string;
readonly sdkCode?: string;
readonly rawValue?: number;

constructor(code: string, message: string, extras?: AdErrorExtras) {
super(message);
this.name = 'AdError';
this.code = code;
this.sdkCode = extras?.sdkCode;
this.rawValue = extras?.rawValue;
}

/** Compact label for UI (badge, logs). */
formatShortLabel(): string {
const parts = [this.code];
if (this.sdkCode) {
parts.push(this.sdkCode);
}
if (this.rawValue !== undefined) {
parts.push(`#${this.rawValue}`);
}
return parts.join(' · ');
}

static fromNativeError(error: any): AdError {
const { code, message } = error.userInfo;
return new AdError(code, message);
const ui = error?.userInfo;
const code = typeof ui?.code === 'string' ? ui.code : 'unknown';
const message =
typeof ui?.message === 'string' ? ui.message : String(ui?.message ?? '');
const sdkCode = typeof ui?.sdkCode === 'string' ? ui.sdkCode : undefined;
let rawValue: number | undefined;
if (typeof ui?.rawValue === 'number' && !Number.isNaN(ui.rawValue)) {
rawValue = ui.rawValue;
} else if (typeof ui?.rawValue === 'string' && ui.rawValue !== '') {
const n = Number(ui.rawValue);
if (!Number.isNaN(n)) {
rawValue = n;
}
}
const extras =
sdkCode !== undefined || rawValue !== undefined
? { sdkCode, rawValue }
: undefined;
return new AdError(code, message, extras);
}
}

Expand Down
Loading