Home > Software engineering >  Dart: try catch not catching the exception from a function that uses 'rethrow'
Dart: try catch not catching the exception from a function that uses 'rethrow'

Time:12-18

I'm trying to use the library livekit_client to create a chat room, I'm trying to handle the exception when the connection fails, this is the code I'm using to connect and catch the error:

try {
      room.connect(
        'ws://localhost:7880',
        'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjEwNjcxMzA2NDgzLCJpc3MiOiJkZXZrZXkiLCJuYW1lIjoidXNlcjEiLCJuYmYiOjE2NzEzMDY0ODMsInN1YiI6InVzZXIxIiwidmlkZW8iOnsicm9vbSI6Im15LWZpcnN0LXJvb20iLCJyb29tSm9pbiI6dHJ1ZX19.SQ2OSWl1CG7UVbui_vmChfmUkYvT3QxKgXd9Yh167ws',
        roomOptions: _roomOptions,
        fastConnectOptions: FastConnectOptions(
          microphone: const TrackOption(enabled: true),
          camera: const TrackOption(enabled: true),
        ),
      );
    } catch (e) {
      print('connection error $e');
    }

but the exception is not being handled and instead the debugger stops at the exception source inside the library files specifically this code:

} catch (error) {
      logger.fine('Connect Error $error');
      _updateConnectionState(ConnectionState.disconnected);
      rethrow;
    }

it stops at the 'rethrow' line

so is 'try catch' has some specifc limitations when used with functions that use 'rethrow'? why is it not catching the exception?

full test code :

import 'package:flutter/material.dart';
import 'package:livekit_client/livekit_client.dart';
import 'package:logging/logging.dart';

void main(List<String> args) {
  Logger.root.level = Level.ALL; // defaults to Level.INFO
  Logger.root.onRecord.listen((record) {
    print('${record.level.name}: ${record.time}: ${record.message}');
  });
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  Room room = Room();
  final RoomOptions _roomOptions = const RoomOptions(
    adaptiveStream: true,
    dynacast: true,
    defaultVideoPublishOptions: VideoPublishOptions(
      simulcast: true,
    ),
    defaultScreenShareCaptureOptions:
        ScreenShareCaptureOptions(useiOSBroadcastExtension: true),
  );

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    print('initializing');
    try {
      room.connect(
        'ws://localhost:7880',
        'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjEwNjcxMzA2NDgzLCJpc3MiOiJkZXZrZXkiLCJuYW1lIjoidXNlcjEiLCJuYmYiOjE2NzEzMDY0ODMsInN1YiI6InVzZXIxIiwidmlkZW8iOnsicm9vbSI6Im15LWZpcnN0LXJvb20iLCJyb29tSm9pbiI6dHJ1ZX19.SQ2OSWl1CG7UVbui_vmChfmUkYvT3QxKgXd9Yh167ws',
        roomOptions: _roomOptions,
        fastConnectOptions: FastConnectOptions(
          microphone: const TrackOption(enabled: true),
          camera: const TrackOption(enabled: true),
        ),
      );
    } catch (e) {
      print('connection error $e');
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(),
    );
  }
}

CodePudding user response:

This is just a guess. But is room.connect() an asynchronous method? It connects to an online server so it must return a Future. Try adding an await keyword. Also, note that you cannot write async/await in the initState method. So maybe try connecting to the server from the main() method, or use a provider.

Your code should look something like this:-

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  try {
    await room.connect();
  } catch (error) {
    // handle error.
  }
  runApp(MyApp());
}
  • Related