Skip to content

VideoPlayerController::initialize can return future which never resolves nor errors when called indirectly from StatefulWidget::initState #151475

@misos1

Description

@misos1

Steps to reproduce

  1. run code samples in debug and release

Expected results

Unhandled exception or printed text "initialized" if it thinks empty string is valid video file.

Actual results

All these tests results below were done in debug. What is even worse is that code sample 2 and code sample 5 crash in release although code sample 2 and 5 should not because error is caught there so it is not possible to catch and handle errors from initialize even in release.

Code sample 1 just stuck there indefinitely after printing "constructed" without ending with an unhandled exception or doing anything.

Code sample 2 tries to catch that error in callback handler but only "constructed" is printed, no error caught and no "initialized" text which should be printed in this case, same result when using try catch.

Code sample 3 provides fake VideoPlayerController and this time unhandled exception is printed correctly:

flutter: constructed
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: 10

Code sample 4 tries to use VideoPlayerController in different context and calls initialize indirectly from main and this time it finally gives error:

flutter: constructed
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: PlatformException(VideoError, Failed to load video: Cannot Open, null, null)

Code sample 5 is code sample 4 with added onError:

flutter: constructed
flutter: error: PlatformException(VideoError, Failed to load video: Cannot Open, null, null)
flutter: initialized

Code sample

Code sample 1
import "dart:io";
import "package:flutter/material.dart";
import "package:video_player/video_player.dart";

void test() async
{
	var vpc = VideoPlayerController.file(File(""));
	print("constructed");
	await vpc.initialize();
	print("initialized");
}

void main()
{
	runApp(const MaterialApp(home: MyHomePage()));
}

class MyHomePage extends StatefulWidget
{
	const MyHomePage({super.key});
	@override State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage>
{
	@override void initState()
	{
		super.initState();
		test();
	}

	@override Widget build(BuildContext context) => const CircularProgressIndicator();
}
Code sample 2
import "dart:io";
import "package:flutter/material.dart";
import "package:video_player/video_player.dart";

void test() async
{
	var vpc = VideoPlayerController.file(File(""));
	print("constructed");
	await vpc.initialize().onError((Object error, StackTrace stackTrace) => print("error: $error"));
	print("initialized");
}

void main()
{
	runApp(const MaterialApp(home: MyHomePage()));
}

class MyHomePage extends StatefulWidget
{
	const MyHomePage({super.key});
	@override State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage>
{
	@override void initState()
	{
		super.initState();
		test();
	}

	@override Widget build(BuildContext context) => const CircularProgressIndicator();
}
Code sample 3
import "dart:io";
import "package:flutter/material.dart";
import "package:video_player/video_player.dart";

class FakeVPC
{
	FakeVPC.file(File f);
	Future<void> initialize()
	{
		return Future.error(10);
	}
}

void test() async
{
	var vpc = FakeVPC.file(File(""));
	print("constructed");
	await vpc.initialize();
	print("initialized");
}

void main()
{
	runApp(const MaterialApp(home: MyHomePage()));
}

class MyHomePage extends StatefulWidget
{
	const MyHomePage({super.key});
	@override State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage>
{
	@override void initState()
	{
		super.initState();
		test();
	}

	@override Widget build(BuildContext context) => const CircularProgressIndicator();
}
Code sample 4
import "dart:io";
import "package:flutter/material.dart";
import "package:video_player/video_player.dart";

void test() async
{
	var vpc = VideoPlayerController.file(File(""));
	print("constructed");
	await vpc.initialize();
	print("initialized");
}

void main()
{
	WidgetsFlutterBinding.ensureInitialized();
	test();
	runApp(const CircularProgressIndicator());
}
Code sample 5
import "dart:io";
import "package:flutter/material.dart";
import "package:video_player/video_player.dart";

void test() async
{
	var vpc = VideoPlayerController.file(File(""));
	print("constructed");
	await vpc.initialize().onError((Object error, StackTrace stackTrace) => print("error: $error"));
	print("initialized");
}

void main()
{
	WidgetsFlutterBinding.ensureInitialized();
	test();
	runApp(const CircularProgressIndicator());
}

Screenshots or Video

Screenshots / Video demonstration

[Upload media here]

Logs

Logs
[Paste your logs here]

Flutter Doctor output

Doctor output
[✓] Flutter (Channel stable, 3.22.2, on macOS 14.5 23F79 darwin-x64)
[✓] Xcode - develop for iOS and macOS (Xcode 15.4)
[✓] Connected device (4 available)
    ! Error: (null) needs to connect to determine its availability. Check the connection between the device and its companion iPhone, and the connection between the iPhone
      and Xcode. Both devices may also need to be restarted and unlocked. (code 1)
> iphone 7 plus
Dart SDK version: 3.4.3 (stable) (Tue Jun 4 19:51:39 2024 +0000) on "macos_x64"

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work listfound in release: 3.22Found to occur in 3.22found in release: 3.24Found to occur in 3.24has reproducible stepsThe issue has been confirmed reproducible and is ready to work onp: video_playerThe Video Player pluginpackageflutter/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