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
23 changes: 23 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,29 @@ jobs:
test -f src/generated/Types.swift || exit 1
test -f src/generated/types.dart || exit 1

- name: Verify generated types are committed (no drift)
run: |
# `bun run generate` is expected to be idempotent: running it
# against the checked-in schema must produce the same bytes
# as the files checked into the repo. If this step fails,
# somebody changed a codegen plugin or the schema without
# re-running `bun run generate` + committing the output.
#
# Use `git status --porcelain` (plus `git diff`) so newly-
# generated but untracked files also fail the check — a
# plain `git diff` would silently pass if the generator
# starts emitting a new target file.
status="$(git status --porcelain)"
if [ -n "$status" ] || ! git diff --exit-code; then
echo ""
echo "::error::Generated types differ from checked-in copies."
echo "Run 'cd packages/gql && bun run generate' locally and commit the result."
echo ""
echo "Untracked or modified paths:"
printf '%s\n' "$status"
exit 1
fi
Comment thread
hyochan marked this conversation as resolved.

test-android:
name: Test Android
runs-on: ubuntu-latest
Expand Down
2 changes: 2 additions & 0 deletions libraries/expo-iap/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ export enum ErrorCode {
RemoteError = 'remote-error',
ServiceDisconnected = 'service-disconnected',
ServiceError = 'service-error',
ServiceTimeout = 'service-timeout',
SkuNotFound = 'sku-not-found',
SkuOfferMismatch = 'sku-offer-mismatch',
SyncError = 'sync-error',
Expand Down Expand Up @@ -1105,6 +1106,7 @@ export interface PurchaseCommon {

export interface PurchaseError {
code: ErrorCode;
debugMessage?: (string | null);
message: string;
productId?: (string | null);
}
Expand Down
1 change: 1 addition & 0 deletions libraries/expo-iap/src/utils/errorMapping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ const COMMON_ERROR_CODE_MAP: Record<ErrorCode, string> = {
[ErrorCode.BillingUnavailable]: ErrorCode.BillingUnavailable,
[ErrorCode.FeatureNotSupported]: ErrorCode.FeatureNotSupported,
[ErrorCode.DuplicatePurchase]: ErrorCode.DuplicatePurchase,
[ErrorCode.ServiceTimeout]: ErrorCode.ServiceTimeout,
[ErrorCode.EmptySkuList]: ErrorCode.EmptySkuList,
[ErrorCode.PurchaseVerificationFailed]: ErrorCode.PurchaseVerificationFailed,
[ErrorCode.PurchaseVerificationFinishFailed]:
Expand Down
3 changes: 3 additions & 0 deletions libraries/flutter_inapp_purchase/lib/helpers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,9 @@ iap_err.PurchaseError convertToPurchaseError(
return iap_err.PurchaseError(
message: result.message ?? 'Unknown error',
code: code,
responseCode: result.responseCode,
debugMessage: result.debugMessage,
platform: platform,
Comment thread
hyochan marked this conversation as resolved.
);
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}

Expand Down
7 changes: 7 additions & 0 deletions libraries/flutter_inapp_purchase/lib/types.dart
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ enum ErrorCode {
ConnectionClosed('connection-closed'),
InitConnection('init-connection'),
ServiceDisconnected('service-disconnected'),
ServiceTimeout('service-timeout'),
QueryProduct('query-product'),
SkuNotFound('sku-not-found'),
SkuOfferMismatch('sku-offer-mismatch'),
Expand Down Expand Up @@ -257,6 +258,8 @@ enum ErrorCode {
return ErrorCode.InitConnection;
case 'service-disconnected':
return ErrorCode.ServiceDisconnected;
case 'service-timeout':
return ErrorCode.ServiceTimeout;
case 'query-product':
return ErrorCode.QueryProduct;
case 'sku-not-found':
Expand Down Expand Up @@ -2570,17 +2573,20 @@ class PurchaseAndroid extends Purchase implements PurchaseCommon {
class PurchaseError {
const PurchaseError({
required this.code,
this.debugMessage,
required this.message,
this.productId,
});

final ErrorCode code;
final String? debugMessage;
final String message;
final String? productId;

factory PurchaseError.fromJson(Map<String, dynamic> json) {
return PurchaseError(
code: ErrorCode.fromJson(json['code'] as String),
debugMessage: json['debugMessage'] as String?,
message: json['message'] as String,
productId: json['productId'] as String?,
);
Expand All @@ -2590,6 +2596,7 @@ class PurchaseError {
return {
'__typename': 'PurchaseError',
'code': code.toJson(),
'debugMessage': debugMessage,
'message': message,
'productId': productId,
};
Expand Down
30 changes: 30 additions & 0 deletions libraries/flutter_inapp_purchase/test/helpers_unit_test.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:convert';

import 'package:flutter_inapp_purchase/enums.dart';
import 'package:flutter_inapp_purchase/errors.dart' as iap_err;
import 'package:flutter_inapp_purchase/helpers.dart';
import 'package:flutter_inapp_purchase/types.dart' as types;
import 'package:flutter_test/flutter_test.dart';
Expand Down Expand Up @@ -582,5 +583,34 @@ void main() {
);
},
);

test(
'convertToPurchaseError forwards debugMessage and responseCode '
'from PurchaseResult',
() {
final result = PurchaseResult.fromJSON(<String, dynamic>{
'responseCode': 5,
'debugMessage':
'Deferred replacement requires the base offer, got a promo offer',
'code': 'developer-error',
'message': 'Invalid arguments provided to the API',
});

final error = convertToPurchaseError(
result,
platform: types.IapPlatform.Android,
);

expect(error, isA<iap_err.PurchaseError>());
expect(error.code, types.ErrorCode.DeveloperError);
expect(error.message, 'Invalid arguments provided to the API');
expect(
error.debugMessage,
'Deferred replacement requires the base offer, got a promo offer',
);
expect(error.responseCode, 5);
expect(error.platform, types.IapPlatform.Android);
},
);
});
}
Loading
Loading