Skip to content

[ios][core] Add public ArgumentsRangeMismatch exception#46901

Merged
tsapeta merged 1 commit into
mainfrom
tsapeta/arguments-range-mismatch-exception
Jun 15, 2026
Merged

[ios][core] Add public ArgumentsRangeMismatch exception#46901
tsapeta merged 1 commit into
mainfrom
tsapeta/arguments-range-mismatch-exception

Conversation

@tsapeta

@tsapeta tsapeta commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Why

The Expo Modules macros synthesize a _decorateModule that binds each @JS function directly onto the module's JS object. Those synthesized bindings need to validate the argument count a JavaScript caller passes. The generated code currently throws an ad-hoc Exception(name: "InvalidArgumentCount", ...), which doesn't express the accepted range (a function with trailing defaulted or optional parameters accepts a span of arities, not one exact count) and isn't a typed exception modules can match on.

This adds a dedicated, public exception purpose-built for that validation, so the synthesized bindings throw a consistent typed error and the message can describe the full accepted range.

How

Added Exceptions.ArgumentsRangeMismatch, a public GenericException<(functionName: String, received: Int, range: ClosedRange<Int>)> in the Exceptions namespace (alongside AppContextLost, etc., which the generated code already references). It carries the function name and the accepted arity range, and renders two message forms:

  • exact arity: 'add' takes 2 argument(s), but received 1
  • range: 'resize' takes from 1 to 2 arguments, but received 3

The paired macro change that emits the range-based arity guard throwing this exception is in expo/expo-modules-macros-plugin#19. This PR is the core half; it must land together with that plugin change, which references this exception.

Test Plan

Exceptions.ArgumentsRangeMismatch is a small, self-contained exception subclass. Its reason text and the ClosedRange<Int> parameter were verified with a standalone Swift check:

'add' takes 2 argument(s), but received 1
'resize' takes from 1 to 2 arguments, but received 3
'opt' takes from 0 to 1 arguments, but received 5

The macro side that emits the throw is covered by expansion tests in the plugin repo (swift test, 86 passing), including new cases for a trailing defaulted parameter, a trailing optional parameter, and an all-omittable signature (required == 0).

@expo-bot expo-bot added the contributor: internal PR author is a member, owner, or collaborator of the expo org label Jun 14, 2026
@expo-bot

expo-bot commented Jun 14, 2026

Copy link
Copy Markdown
Collaborator

The Pull Request introduced fingerprint changes against the base commit: bf53229

Fingerprint diff
[
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/@expo/log-box",
      "reasons": [
        "expoAutolinkingIos",
        "expoAutolinkingAndroid"
      ],
      "hash": "624a0f8819f458a3c028e64d66e6fd5c563f6c5c"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/@expo/log-box",
      "reasons": [
        "expoAutolinkingIos",
        "expoAutolinkingAndroid"
      ],
      "hash": "f1fd7e5251213640b46adb4a8aaeb097b528015d"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/expo",
      "reasons": [
        "expoAutolinkingIos",
        "expoAutolinkingAndroid",
        "expoConfigPlugins",
        "expoConfigPlugins",
        "rncoreAutolinkingAndroid",
        "rncoreAutolinkingIos"
      ],
      "hash": "29e73509d1867dbf5e936189fd789154f78d295e"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/expo",
      "reasons": [
        "expoAutolinkingIos",
        "expoAutolinkingAndroid",
        "expoConfigPlugins",
        "expoConfigPlugins",
        "rncoreAutolinkingAndroid",
        "rncoreAutolinkingIos"
      ],
      "hash": "1037f9b4bb2e96d8ec41f0d8366843482bf23703"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/expo-dev-launcher",
      "reasons": [
        "expoAutolinkingIos",
        "expoAutolinkingAndroid"
      ],
      "hash": "b3aa40e8bff13a2e373dc3df688b849b23f820b3"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/expo-dev-launcher",
      "reasons": [
        "expoAutolinkingIos",
        "expoAutolinkingAndroid"
      ],
      "hash": "3d257c8c7aa9feb2bda78dc9fa3fd06d9c672afb"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/expo-dev-menu",
      "reasons": [
        "expoAutolinkingIos",
        "expoAutolinkingAndroid"
      ],
      "hash": "1f691f9b25b7fbcb0fadf2cec47caab640df6adf"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/expo-dev-menu",
      "reasons": [
        "expoAutolinkingIos",
        "expoAutolinkingAndroid"
      ],
      "hash": "9ba1fdd7759182194436f37ab2ec5515b6c578ea"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/expo-gl",
      "reasons": [
        "expoAutolinkingIos",
        "expoAutolinkingAndroid"
      ],
      "hash": "004fbfdb83f3ba2b5eda2b957c89dcec0a85ca4e"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/expo-gl",
      "reasons": [
        "expoAutolinkingIos",
        "expoAutolinkingAndroid"
      ],
      "hash": "53b4409ee69f302f7d6120e1c1d9ddfd17fcd350"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/expo-modules-core",
      "reasons": [
        "expoAutolinkingIos",
        "expoAutolinkingAndroid",
        "expoAutolinkingIos"
      ],
      "hash": "0baa6fa271b35ec55976cf25c5d9eb5bebb27b7c"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/expo-modules-core",
      "reasons": [
        "expoAutolinkingIos",
        "expoAutolinkingAndroid",
        "expoAutolinkingIos"
      ],
      "hash": "5ac145361f7377ad64233034f4bc3f62a09b6b53"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "node_modules/@shopify/react-native-skia",
      "reasons": [
        "rncoreAutolinkingAndroid"
      ],
      "hash": "405d98d51272d063c6876e7be93c5e392abf3cd7"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "node_modules/@shopify/react-native-skia",
      "reasons": [
        "rncoreAutolinkingAndroid"
      ],
      "hash": "3f9e1aacb7f75a36f2668ba943381096ba26eac4"
    }
  }
]

Generated by PR labeler 🤖

@expo-bot expo-bot added the bot: passed checks ExpoBot has nothing to complain about label Jun 14, 2026
@tsapeta tsapeta marked this pull request as ready for review June 14, 2026 20:24
@tsapeta tsapeta requested a review from Kudo June 14, 2026 20:24
@github-actions

This comment was marked as resolved.

Add `Exceptions.ArgumentsRangeMismatch`, a public `GenericException`
carrying the function name, the received count, and the accepted arity
bounds (required count and maximum). The Expo Modules macros' synthesized
`@JS` function bindings throw it when a JS caller passes a number of
arguments outside the range the native function accepts, replacing an
ad-hoc `Exception(name: "InvalidArgumentCount", ...)` the generated code
used.

The message reads either "'add' takes 2 argument(s), but received 1" for
an exact arity, or "'resize' takes from 1 to 2 arguments, but received 3"
for a range.
@tsapeta tsapeta force-pushed the tsapeta/arguments-range-mismatch-exception branch from d132e7b to 617dd0b Compare June 14, 2026 20:32
@tsapeta tsapeta changed the title [ios][modules-core] Add public ArgumentsRangeMismatch exception [ios][core] Add public ArgumentsRangeMismatch exception Jun 14, 2026
@tsapeta tsapeta merged commit 6514e9e into main Jun 15, 2026
22 of 23 checks passed
@tsapeta tsapeta deleted the tsapeta/arguments-range-mismatch-exception branch June 15, 2026 14:50
likeSo pushed a commit to likeSo/expo that referenced this pull request Jun 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bot: fingerprint changed bot: passed checks ExpoBot has nothing to complain about contributor: internal PR author is a member, owner, or collaborator of the expo org

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants