Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PdfViewer.data: dispose issue when recalled as disposed not finished. #246

Open
BenDevExatech opened this issue Oct 13, 2024 · 6 comments
Open
Labels
bug Something isn't working wait for response Wait for the issue author (or some user) response

Comments

@BenDevExatech
Copy link

BenDevExatech commented Oct 13, 2024

Hi there!

First of all, congratulations for the efforts made to produce a such rich and malleable package.

I'm facing a specific issue with the PdfViewer.data class:
On a layout, I display a list of PDF items, associated with the display of the selected PDF via its Uint8List content.
The problem I'm having is that if I move too quickly from one pdf to another in the list, I get a crash exception which seems to be due to a dispose maybe not yet finished inside the package:

first the debug stops in the dispose function in the file pdfrx_web.dart :
@override Future<void> dispose() async { _document.destroy(); onDispose?.call(); }

And then crashes:

══╡ EXCEPTION CAUGHT BY ANIMATION LIBRARY ╞═════════════════════════════════════════════════════════
The following TypeErrorImpl was thrown while notifying listeners for AnimationController:
Unexpected null value.

When the exception was thrown, this was the stack:
dart-sdk/lib/internal/js_dev_runtime/private/ddc_runtime/errors.dart 296:3 throw
errors.dart:296
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 606:18 nullCheck
operations.dart:606
packages/pdfrx/src/widgets/pdf_viewer.dart 1170:59 [_makeMatrixInSafeRange]
pdf_viewer.dart:1170
packages/pdfrx/src/widgets/pdf_viewer.dart 1611:26 set value
pdf_viewer.dart:1611
packages/pdfrx/src/widgets/pdf_viewer.dart 1355:7 update
pdf_viewer.dart:1355
packages/flutter/src/animation/listener_helpers.dart 161:11 notifyListeners
listener_helpers.dart:161
packages/flutter/src/animation/animation_controller.dart 908:5 [_tick]
animation_controller.dart:908
packages/flutter/src/scheduler/ticker.dart 261:12 [_tick]
ticker.dart:261
packages/flutter/src/scheduler/binding.dart 1397:7 [_invokeFrameCallback]
binding.dart:1397
packages/flutter/src/scheduler/binding.dart 1240:11
binding.dart:1240
dart-sdk/lib/_internal/js_dev_runtime/private/linked_hash_map.dart 21:7 forEach
linked_hash_map.dart:21
packages/flutter/src/scheduler/binding.dart 1238:16 handleBeginFrame
binding.dart:1238
packages/flutter/src/scheduler/binding.dart 1155:5 [_handleBeginFrame]
binding.dart:1155
lib/_engine/engine/platform_dispatcher.dart 1423:5 invoke1
platform_dispatcher.dart:1423
lib/_engine/engine/platform_dispatcher.dart 287:5 invokeOnBeginFrame
platform_dispatcher.dart:287
lib/_engine/engine/initialization.dart 177:36
initialization.dart:177
dart-sdk/lib/_internal/js_dev_runtime/patch/js_allow_interop_patch.dart 188:27 _callDartFunctionFast1
js_allow_interop_patch.dart:188

The AnimationController notifying listeners was:
AnimationController#bf22f(⏭ 1.000; paused)
════════════════════════════════════════════════════════════════════════════════════════════════════
RethrownDartError: RenderingCancelledException: Rendering cancelled, page 1
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 329:10 createErrorWithStack
errors.dart:329
dart-sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart 265:28 _throw
core_patch.dart:265
dart-sdk/lib/core/errors.dart 120:5 throwWithStackTrace
errors.dart:120
dart-sdk/lib/async/zone.dart 1386:11 callback
zone.dart:1386
dart-sdk/lib/async/schedule_microtask.dart 40:11 _microtaskLoop
schedule_microtask.dart:40
dart-sdk/lib/async/schedule_microtask.dart 49:5 _startMicrotaskLoop
schedule_microtask.dart:49
dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 181:7

Note 1: I'm using statefull widget context and I get the UInt8List data change from didUpdateWidget function.
Note 2: everything works fine if I let each pdf load finish before selecting another pdf.

Thank you in advance for your kind feedback.
Ben.

EDIT: Sorry, I forgot to put my project details:
Project details
Flutter sdk: 3.24.2
Dart sdk: 3.5.2
pdfrx version: ^1.0.84

@espresso3389 espresso3389 added the bug Something isn't working label Nov 2, 2024
@BenDevExatech
Copy link
Author

Hello @espresso3389,

I saw you flagged the ticket as "bug".
Does it mean that you were able to reproduce the issue?
Or do you need addtionnal context information?

@espresso3389
Copy link
Owner

espresso3389 commented Nov 12, 2024

No, I could not reproduce the issue. But the behavier seems to be a bug. I need more info to reproduce the issue.

@BenDevExatech
Copy link
Author

Ok, I'm gonna check as soon as possible if I can give you a simple sample that can leads easily to the issue.

@BenDevExatech
Copy link
Author

Hello,

I took some time to try to reproduce my issue in a more generic context.
Unfortunately I wasn't able to get the exact same issue.
Perhaps because on our app, we are working in a mobx context which performs rebuilds on specific blocks based on observable variables...
While for this test I used classic setState() to update local variable for rebuild.

However, I still encountered specific uncaught crashes.
In the attached .zip file:
widget_pdfrx_viewer_testing.zip

you will find 3 files :

  1. widget_pdfrx_viewer.dart: a pdf viewer component based on a use of the PdfViewer.data class (feeded with the pdf Uint8List content)
  2. widget_pdf_testing_local_like.dart: an interface that lists pdf files with the viewer of the selected file.
    The list and pdf content to display are based on a "local" mode for datas feeding
  3. widget_pdf_testing_client_server_like.dart: an interface that lists pdf files with the viewer of the selected file.
    The list and pdf content to display are based on a "client/server" mode for datas feeding.

NOTE : For the pdf file list, the layouts use local files. So to work with the layouts in your context, you will have to put your own local file paths in the variable "List pdfMediaList" :

image


Specific crash :
In the use of those interfaces, I faced a specific crash on the widget_pdf_testing_local_like.dart layout :
On a multipage pdf, if I display for example page 2, and then I select in the list a pdf that only has 1 page, then the app crashes on the "_guessCurrentPage()" function in the file "...\Pub\Cache\hosted\pub.dev\pdfrx-1.0.84\lib\src\widgets\pdf_viewer.dart" :

image

Common crash :
A common crash with the use of both layouts (local and client/server) :
If you click too quickly on different files in the list, you end up with a crash on the "_makeMatrixInSafeRange(Matrix4 newValue)" function in the same file "...\Pub\Cache\hosted\pub.dev\pdfrx-1.0.84\lib\src\widgets\pdf_viewer.dart"

image

This last one is more like the issue I'm facing in our app, even if in our specific case the crash occurs in the "dispose()" function in the file "...\Pub\Cache\hosted\pub.dev\pdfrx-1.0.84\lib\src\web\pdfrx_web.dart"

image

So that's it, I hope you will be able to check this on your side ;)
cordially,
Ben.

@espresso3389
Copy link
Owner

@BenDevExatech

I've tested with pdfrx 1.0.96 and the following code and could not cause any crashes:

  List<String> pdfMediaList = [
    r"D:\pdfrx\example\viewer\assets\hello.pdf",
    r"D:\pdfrx\example\viewer\assets\rotate-test.pdf",
    r"D:\pdfrx\example\viewer\assets\single.pdf",
  ];
import 'package:flutter/material.dart';

import 'widget_pdf_testing_local_like.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

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

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: WidgetPdfTestingLocalLike(),
    );
  }
}

@espresso3389 espresso3389 added the wait for response Wait for the issue author (or some user) response label Dec 12, 2024
@BenDevExatech
Copy link
Author

@espresso3389
Hello,
Ok, I checked few days ago with the 1.0.93 and I still got the crash.
I will check tomorrow with the 1.0.96 or 1.0.97 (I'm in France so for now it's time to go to bed ;) )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working wait for response Wait for the issue author (or some user) response
Projects
None yet
Development

No branches or pull requests

2 participants