stephanrauh / ngx-extended-pdf-viewer

A full-blown PDF viewer for Angular 16, 17, and beyond
https://pdfviewer.net
Apache License 2.0
473 stars 181 forks source link

Console errors when initialization breaks #804

Closed Rafal1 closed 2 years ago

Rafal1 commented 3 years ago

Version of ngx-extended-pdf-viewer: 9.0.2 Browser: Firefox 89.0

I have a following structre in my code (all empty params are filled but not necessary here):

file-view.component.html

...
<div *ngIf="calculatedVariable1">
    <div *ngIf="calculatedVariable2">
        <ngx-extended-pdf-viewer 
                [style.maxHeight.px]=""
                [style.minHeight.px]=""
                class=""
                useBrowserLocale=""
                #pdfViewer
                theme=""
                *ngIf="calculatedVariable3"
                [src]=""
                [textLayer]="">
        </ngx-extended-pdf-viewer>
    </div>
</div>
...

main-screen.component.html

...
<app-file-view *ngIf="calculatedVariable4" [height]="" #fileView></app-file-view>
...

If I enter to main-screen and right after that (ngx-extended-pdf-viewer is during the initialization, it is loading my pdf) I click back to the previous site in the browser. I got following errors (not at every try!). Everything works fine if I wait a bit longer but I don't want my users could see those errors in console.

I've prepared a simple app to reproduce the issues (I couldn't make a stackblitz/codesandbox exmple cause https://github.com/stephanrauh/ngx-extended-pdf-viewer/issues/68). You will be able to reproduce 3 of 4 errors. The last one occurs in my app but it requires nested components which I was unable to reproduce in my example app :( but it's also related with delayed initialization.

1) unproduceable in example app:

ERROR Error: Uncaught (in promise): Error: The `container` must be absolutely positioned.
BaseViewer@http://localhost:4200/assets/viewer-2.7.684.min.js:43:159974
PDFViewer@http://localhost:4200/assets/viewer-2.7.684.min.js:43:157995
_initializeViewerComponents@http://localhost:4200/assets/viewer-2.7.684.min.js:43:17653
initialize@http://localhost:4200/assets/viewer-2.7.684.min.js:43:13939
async*run@http://localhost:4200/assets/viewer-2.7.684.min.js:43:20026
webViewerLoad@http://localhost:4200/assets/viewer-2.7.684.min.js:43:7016
doInitPDFViewer/<@http://localhost:4200/vendor.js:129386:24
timer@http://localhost:4200/polyfills.js:12602:41
invokeTask@http://localhost:4200/polyfills.js:10447:31
onInvokeTask@http://localhost:4200/vendor.js:56179:33
invokeTask@http://localhost:4200/polyfills.js:10446:60
runTask@http://localhost:4200/polyfills.js:10219:47
invokeTask@http://localhost:4200/polyfills.js:10528:34
ZoneTask/this.invoke@http://localhost:4200/polyfills.js:10517:48
scheduleTask/data.args[0]@http://localhost:4200/polyfills.js:12582:32
setTimeout handler*scheduleTask@http://localhost:4200/polyfills.js:12584:35
scheduleTask@http://localhost:4200/polyfills.js:10434:26
onScheduleTask@http://localhost:4200/polyfills.js:10324:65
scheduleTask@http://localhost:4200/polyfills.js:10427:51
scheduleTask@http://localhost:4200/polyfills.js:10262:43
scheduleMacroTask@http://localhost:4200/polyfills.js:10285:25
scheduleMacroTaskWithCurrentZone@http://localhost:4200/polyfills.js:10720:25
patchTimer/setNative</<@http://localhost:4200/polyfills.js:12626:62
patchMethod/proto[name]@http://localhost:4200/polyfills.js:11016:24
doInitPDFViewer@http://localhost:4200/vendor.js:129374:19
ngAfterViewInit@http://localhost:4200/vendor.js:129234:26
callHook@http://localhost:4200/vendor.js:30057:22
callHooks@http://localhost:4200/vendor.js:30026:25
executeInitAndCheckHooks@http://localhost:4200/vendor.js:29977:18
refreshView@http://localhost:4200/vendor.js:37043:45
refreshEmbeddedViews@http://localhost:4200/vendor.js:38097:28
refreshView@http://localhost:4200/vendor.js:36996:29
refreshEmbeddedViews@http://localhost:4200/vendor.js:38097:28
refreshView@http://localhost:4200/vendor.js:36996:29
refreshEmbeddedViews@http://localhost:4200/vendor.js:38097:28
refreshView@http://localhost:4200/vendor.js:36996:29
refreshComponent@http://localhost:4200/vendor.js:38143:24
refreshChildComponents@http://localhost:4200/vendor.js:36769:25
[fileviewer-app.zip](https://github.com/stephanrauh/ngx-extended-pdf-viewer/files/6636835/fileviewer-app.zip)
[fileviewer-app.zip](https://github.com/stephanrauh/ngx-extended-pdf-viewer/files/6636839/fileviewer-app.zip)
[fileviewer-app.zip](https://github.com/stephanrauh/ngx-extended-pdf-viewer/files/6636842/fileviewer-app.zip)

refreshView@http://localhost:4200/vendor.js:37022:35
refreshEmbeddedViews@http://localhost:4200/vendor.js:38097:28
refreshView@http://localhost:4200/vendor.js:36996:29
refreshComponent@http://localhost:4200/vendor.js:38143:24
refreshChildComponents@http://localhost:4200/vendor.js:36769:25
refreshView@http://localhost:4200/vendor.js:37022:35
refreshEmbeddedViews@http://localhost:4200/vendor.js:38097:28
    Angular 20
    run app.js:621
    webViewerLoad viewer.js:266
    doInitPDFViewer ngx-extended-pdf-viewer.js:1441
    Angular 17
    doInitPDFViewer ngx-extended-pdf-viewer.js:1429
    ngAfterViewInit ngx-extended-pdf-viewer.js:1289
    Angular 19
core.js:6456

2)

ERROR Error: Uncaught (in promise): Error: Transport destroyed
getPage/i<@http://localhost:4200/assets/viewer-2.9.149.min.js:22:53066
invoke@http://localhost:4200/polyfills.js:377:30
onInvoke@http://localhost:4200/vendor.js:43769:33
invoke@http://localhost:4200/polyfills.js:376:36
run@http://localhost:4200/polyfills.js:136:47
scheduleResolveOrReject/<@http://localhost:4200/polyfills.js:870:40
invokeTask@http://localhost:4200/polyfills.js:412:35
onInvokeTask@http://localhost:4200/vendor.js:43747:33
invokeTask@http://localhost:4200/polyfills.js:411:40
runTask@http://localhost:4200/polyfills.js:180:51
drainMicroTaskQueue@http://localhost:4200/polyfills.js:582:39
invokeTask@http://localhost:4200/polyfills.js:497:25
invokeTask@http://localhost:4200/polyfills.js:1634:18
globalZoneAwareCallback@http://localhost:4200/polyfills.js:1671:35
EventListener.handleEvent*customScheduleGlobal@http://localhost:4200/polyfills.js:1786:47
scheduleTask@http://localhost:4200/polyfills.js:398:30
onScheduleTask@http://localhost:4200/polyfills.js:285:69
scheduleTask@http://localhost:4200/polyfills.js:391:55
scheduleTask@http://localhost:4200/polyfills.js:223:47
scheduleEventTask@http://localhost:4200/polyfills.js:249:29
makeAddListener/<@http://localhost:4200/polyfills.js:1941:39
MessageHandler@http://localhost:4200/assets/viewer-2.9.149.min.js:22:110869
_initialize@http://localhost:4200/assets/viewer-2.9.149.min.js:22:43975
PDFWorker@http://localhost:4200/assets/viewer-2.9.149.min.js:22:43387
getDocument@http://localhost:4200/assets/viewer-2.9.149.min.js:22:26672
open@http://localhost:4200/assets/viewer-2.9.149.min.js:43:17131
openPDF@http://localhost:4200/vendor.js:73696:38
callback/this.initTimeout<@http://localhost:4200/vendor.js:73249:26
invokeTask@http://localhost:4200/polyfills.js:412:35
onInvokeTask@http://localhost:4200/vendor.js:43747:33
invokeTask@http://localhost:4200/polyfills.js:411:40
runTask@http://localhost:4200/polyfills.js:180:51
invokeTask@http://localhost:4200/polyfills.js:493:38
ZoneTask/this.invoke@http://localhost:4200/polyfills.js:482:52
timer@http://localhost:4200/polyfills.js:2565:33
setTimeout handler*scheduleTask@http://localhost:4200/polyfills.js:2586:39
scheduleTask@http://localhost:4200/polyfills.js:398:30
onScheduleTask@http://localhost:4200/polyfills.js:285:69
scheduleTask@http://localhost:4200/polyfills.js:391:55
scheduleTask@http://localhost:4200/polyfills.js:223:47
scheduleMacroTask@http://localhost:4200/polyfills.js:246:29
scheduleMacroTaskWithCurrentZone@http://localhost:4200/polyfills.js:1147:29
patchTimer/setNative</<@http://localhost:4200/polyfills.js:2599:66
patchMethod/proto[name]@http://localhost:4200/polyfills.js:1462:52
callback@http://localhost:4200/vendor.js:73244:32
invokeTask@http://localhost:4200/polyfills.js:412:35
onInvokeTask@http://localhost:4200/vendor.js:43747:33
invokeTask@http://localhost:4200/polyfills.js:411:40
runTask@http://localhost:4200/polyfills.js:180:51
invokeTask@http://localhost:4200/polyfills.js:493:38
invokeTask@http://localhost:4200/polyfills.js:1634:18
globalZoneAwareCallback@http://localhost:4200/polyfills.js:1671:35
fireL10nReadyEvent@http://localhost:4200/assets/viewer-2.9.149.min.js:43:235425
d@http://localhost:4200/assets/viewer-2.9.149.min.js:43:237524
parseResource/</<@http://localhost:4200/assets/viewer-2.9.149.min.js:43:237211
parseProperties/<@http://localhost:4200/assets/viewer-2.9.149.min.js:43:237052
nextEntry@http://localhost:4200/assets/viewer-2.9.149.min.js:43:236546
nextEntry@http://localhost:4200/assets/viewer-2.9.149.min.js:43:236546
parseRawLines@http://localhost:4200/assets/viewer-2.9.149.min.js:43:236826
loadImport/<@http://localhost:4200/assets/viewer-2.9.149.min.js:43:236894
xhrLoadText/n.onreadystatechange@http://localhost:4200/assets/viewer-2.9.149.min.js:43:235721
wrapFn@http://localhost:4200/polyfills.js:1231:43
invokeTask@http://localhost:4200/polyfills.js:412:35
runTask@http://localhost:4200/polyfills.js:180:51
invokeTask@http://localhost:4200/polyfills.js:493:38
    Angular 18
    MessageHandler pdf_layer_viewer.js:32
    _initialize app.js:2801
    PDFWorker app.js:2778
    getDocument app.js:1732
    open app.js:922
    openPDF ngx-extended-pdf-viewer.js:1851
    initTimeout ngx-extended-pdf-viewer.js:1404
    Angular 16
    callback ngx-extended-pdf-viewer.js:1399
    Angular 7
    fireL10nReadyEvent l10n.js:102
    d l10n.js:383
    parseResource l10n.js:318
    parseProperties l10n.js:283
    nextEntry l10n.js:215
    nextEntry l10n.js:215
    parseRawLines l10n.js:262
    loadImport l10n.js:270
    onreadystatechange l10n.js:117
    Angular 4
core.js:6185:19
    Angular 4
    RxJS 5
    Angular 20
    MessageHandler pdf_layer_viewer.js:32
    _initialize app.js:2801
    PDFWorker app.js:2778
    getDocument app.js:1732
    open app.js:922
    openPDF ngx-extended-pdf-viewer.js:1851
    initTimeout ngx-extended-pdf-viewer.js:1404
    Angular 16
    callback ngx-extended-pdf-viewer.js:1399
    Angular 7
    fireL10nReadyEvent l10n.js:102
    d l10n.js:383
    parseResource l10n.js:318
    parseProperties l10n.js:283
    nextEntry l10n.js:215
    nextEntry l10n.js:215
    parseRawLines l10n.js:262
    loadImport l10n.js:270
    onreadystatechange l10n.js:117
    Angular 4

3)

    PDFViewer.scrollPageIntoView: "1" is not a valid pageNumber parameter. base_viewer.js:925:6
    scrollPageIntoView base_viewer.js:925
    _setScaleUpdatePages base_viewer.js:770
    _setScale base_viewer.js:811
    set currentScaleValue base_viewer.js:397
    setZoom ngx-extended-pdf-viewer.js:2256
    fulfilled tslib.es6.js:73
    Angular 24
    adopt tslib.es6.js:71
    ZoneAwarePromise Angular
    adopt tslib.es6.js:71
    step tslib.es6.js:75
    __awaiter tslib.es6.js:76
    ZoneAwarePromise Angular
    __awaiter tslib.es6.js:72
    setZoom ngx-extended-pdf-viewer.js:2206
    openPDF ngx-extended-pdf-viewer.js:1853
    __awaiter tslib.es6.js:76
    ZoneAwarePromise Angular
    __awaiter tslib.es6.js:72
    openPDF ngx-extended-pdf-viewer.js:1853
    Angular 10

4)

    Uncaught (in promise) TypeError: this.messageHandler is null
    startCleanup ui_utils.js:468
    cleanup app.js:2024
    _cleanup app.js:1849
    Angular 16
    renderHighestPriority pdf_rendering_queue.js:89
    renderView pdf_rendering_queue.js:171
    Angular 16
    promise callback*get genericl10n.js:43
    reset pdf_page_view.js:266
    cleanup base_viewer.js:1250
    _cleanup app.js:1841
    ngOnDestroy ngx-extended-pdf-viewer.js:1942
    Angular 14
    RxJS 10
    ui_utils.js:468:4
Rafal1 commented 3 years ago

Here is an app:

fileviewer-app.zip

stephanrauh commented 3 years ago

Maybe I can add a customizable filter. More precisely, I could call a user-defined function that filters the error message before logging. So you can decide yourself which error messages to show. Or you could even send the messages to the server instead of logging them on the client (inspired by https://github.com/log4js-node/logstashHTTP and similar frameworks).

Rafal1 commented 3 years ago

Those initialization problems seem to be hard to solve directly (maybe we got any idea in the future) so suggested error managing mechanism would be a nice tool to see how often they occur for end users, maybe we even log something new.

stephanrauh commented 3 years ago

I haven't checked it yet - but I've improved ngDestroy() after realizing the close() method of pdf.js is asynchronous. Maybe this already helps.

Rafal1 commented 3 years ago

I've checked only a basic case on a current 10.0.0-alpha.8 version. Error No 2 from the list still occurs.


ERROR Error: Uncaught (in promise): Error: Transport destroyed
stephanrauh commented 3 years ago

Does that mean the other errors are gone? That'd be great news!

Implementing a message filter is still on my ship list for version 10. Fun fact: I already had an implementation, but I threw it away because it wouldn't work. After several days, I learned that the new version of ng-packagr is broken. My implementation was probably OK :(

stephanrauh commented 2 years ago

The filter has landed with version 11.0.0-alpha.4:

Window['ngxConsoleFilter'] = (level: string, message: any): boolean => {
  return true;
}
export class NgxConsole {
  public log(message: any): void {
    if (Window['ngxConsoleFilter']('log', message)) {
      console.log(message);
    }
  }
  public error(message: any): void {
    if (Window['ngxConsoleFilter']('error', message)) {
      console.error(message);
    }

  }
  public warn(message: any): void {
    if (Window['ngxConsoleFilter']('warn', message)) {
      console.warn(message);
    }
  }
}

Window['ngxConsole'] = new NgxConsole();
stephanrauh commented 2 years ago

I've added the documentation of the feature to the showcase project.