Skip to content

[pigeon] KotlinOptions errorClassName not used in Kotlin to Dart communication #139031

@NathanKolbas

Description

@NathanKolbas

Is there an existing issue for this?

What package does this bug report belong to?

pigeon

What target platforms are you seeing this bug on?

Android

Have you already upgraded your packages?

Yes

Dependency versions

pubspec.lock
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
...
  analyzer:
    dependency: transitive
    description:
      name: analyzer
      sha256: ea3d8652bda62982addfd92fdc2d0214e5f82e43325104990d4f4c4a2a313562
      url: "https://pub.dev"
    source: hosted
    version: "5.13.0"
  args:
    dependency: transitive
    description:
      name: args
      sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596
      url: "https://pub.dev"
    source: hosted
    version: "2.4.2"
  collection:
    dependency: transitive
    description:
      name: collection
      sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
      url: "https://pub.dev"
    source: hosted
    version: "1.17.2"
  meta:
    dependency: transitive
    description:
      name: meta
      sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
      url: "https://pub.dev"
    source: hosted
    version: "1.9.1"
  path:
    dependency: transitive
    description:
      name: path
      sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
      url: "https://pub.dev"
    source: hosted
    version: "1.8.3"
  pigeon:
    dependency: "direct dev"
    description:
      name: pigeon
      sha256: c897b1abb2fa1d8fdb61aca34216796160ca7d9e34fef360a733e2608191acd4
      url: "https://pub.dev"
    source: hosted
    version: "14.0.0"
  yaml:
    dependency: transitive
    description:
      name: yaml
      sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5"
      url: "https://pub.dev"
    source: hosted
    version: "3.1.2"
...
sdks:
  dart: ">=3.1.4 <4.0.0"
  flutter: ">=3.7.0"

Steps to reproduce

  1. Create a pigeon that uses Kotlin to Dart communication (i.e. FlutterApi). Here is some example code:
@ConfigurePigeon(PigeonOptions(
  dartOut: 'lib/pigeon/host_calls_dart_pigeon.g.dart',
  kotlinOut: 'android/app/src/main/kotlin/.../pigeon/HostCallsDartPigeon.g.kt',
    kotlinOptions: KotlinOptions(
        errorClassName: 'HostCallsDartPigeonFlutterError'
    )
))
@FlutterApi()
abstract class HostCallsDartPigeon {
  bool example();
}
  1. Run the generator e.g. dart run pigeon --input pigeons/host_calls_dart_pigeon.dart
  2. Output does not use HostCallsDartPigeonFlutterError:
// Autogenerated from Pigeon (v14.0.0), do not edit directly.
// See also: https://pub.dev/packages/pigeon


import android.util.Log
import io.flutter.plugin.common.BasicMessageChannel
import io.flutter.plugin.common.BinaryMessenger
import io.flutter.plugin.common.MessageCodec
import io.flutter.plugin.common.StandardMessageCodec
import java.io.ByteArrayOutputStream
import java.nio.ByteBuffer

private fun createConnectionError(channelName: String): FlutterError {
  return FlutterError("channel-error",  "Unable to establish connection on channel: '$channelName'.", "")}

/**
 * Error class for passing custom error details to Flutter via a thrown PlatformException.
 * @property code The error code.
 * @property message The error message.
 * @property details The error details. Must be a datatype supported by the api codec.
 */
class HostCallsDartPigeonFlutterError (
  val code: String,
  override val message: String? = null,
  val details: Any? = null
) : Throwable()
/** Generated class from Pigeon that represents Flutter messages that can be called from Kotlin. */
@Suppress("UNCHECKED_CAST")
class HostCallsDartPigeon(private val binaryMessenger: BinaryMessenger) {
  companion object {
    /** The codec used by HostCallsDartPigeon. */
    val codec: MessageCodec<Any?> by lazy {
      StandardMessageCodec()
    }
  }
  fun example(callback: (Result<Boolean>) -> Unit) {
    val channelName = "....HostCallsDartPigeon.isHomeScreenVisible"
    val channel = BasicMessageChannel<Any?>(binaryMessenger, channelName, codec)
    channel.send(null) {
      if (it is List<*>) {
        if (it.size > 1) {
          callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?)))
        } else if (it[0] == null) {
          callback(Result.failure(FlutterError("null-error", "Flutter api returned null value for non-null return value.", "")))
        } else {
          val output = it[0] as Boolean
          callback(Result.success(output))
        }
      } else {
        callback(Result.failure(createConnectionError(channelName)))
      } 
    }
  }
}

Expected results

Kotlin's example method should use HostCallsDartPigeonFlutterError instead of FlutterError when specified.

This all started with separating my pigeons into multiple files. Since each file uses FlutterError I would get Redeclaration: FlutterError. To resolve this, I set the errorClassName in the kotlinOptions of the @ConfigurePigeon.

Is there a better way to approach this or something that could be improved in pigeon to better handle multiple files of pigeons? I also noticed I can't seem to supply multiple files to --input.

Actual results

Kotlin's example method uses FlutterError.

Code sample

Code sample
@ConfigurePigeon(PigeonOptions(
  dartOut: 'lib/pigeon/host_calls_dart_pigeon.g.dart',
  kotlinOut: 'android/app/src/main/kotlin/.../pigeon/HostCallsDartPigeon.g.kt',
    kotlinOptions: KotlinOptions(
        errorClassName: 'HostCallsDartPigeonFlutterError'
    )
))
@FlutterApi()
abstract class HostCallsDartPigeon {
  bool example();
}

Screenshots or Videos

Screenshots / Video demonstration

[Upload media here]

Logs

Logs
[Paste your logs here]

Flutter Doctor output

Doctor output
Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel stable, 3.13.8, on Microsoft Windows [Version 10.0.19045.3693], locale en-US)
[√] Windows Version (Installed version of Windows is version 10 or higher)
[√] Android toolchain - develop for Android devices (Android SDK version 33.0.1)
[√] Chrome - develop for the web
[√] Visual Studio - develop Windows apps (Visual Studio Community 2019 16.11.22)
[√] Android Studio (version 2022.3)
[√] VS Code (version 1.83.1)
[√] Connected device (3 available)
[√] Network resources

• No issues found!

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work listfound in release: 3.16Found to occur in 3.16found in release: 3.17Found to occur in 3.17has reproducible stepsThe issue has been confirmed reproducible and is ready to work onp: pigeonrelated to pigeon messaging codegen toolpackageflutter/packages repository. See also p: labels.r: fixedIssue is closed as already fixed in a newer versionteam-ecosystemOwned by Ecosystem teamtriaged-ecosystemTriaged by Ecosystem team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions