Skip to content

fix(decorators): Gracefully Handle File Read Errors#53

Merged
jourdain merged 5 commits intoKitware:masterfrom
snacksbro:master
Mar 24, 2026
Merged

fix(decorators): Gracefully Handle File Read Errors#53
jourdain merged 5 commits intoKitware:masterfrom
snacksbro:master

Conversation

@snacksbro
Copy link
Copy Markdown
Contributor

@snacksbro snacksbro commented Mar 19, 2026

This PR makes the fileHandler decorator handle errors that File objects throw if their content is unreadable due to permission errors. This can occur if the browser submits multiple files to Trame and one of them is unreadable, resulting in a JS error being thrown to the console. This modifies the fileHandler code to append a new key to the object, error, containing the error message reported from the FileReader object. That way, the server code can read this per-file and deduce which files had an error while uploading.

I do notice that there's another fileHandler in js-lib, is this to be updated as well?

Demo

Below is an example of how a consumer may use this new error field on the serialized File dictionaries from the client. In this, the callback for update_modelValue will always run despite any errors processing the files, that way the ones that uploaded without errors can still be processed while also being able to annotate which files weren't able to be processed due to errors while uploading.

"""Example to showcase an error with uploading files if one of the files lacks proper permissions.

This used the following dependencies:

trame==3.12.0
trame-client==3.11.3
trame-common==1.1.2
trame-server==3.10.0
trame-vuetify==3.2.1

This example can be ran inside an environment with the above via:

python input-upload-mre.py
"""

from __future__ import annotations


from trame.app import get_server
from trame.decorators import TrameApp
from trame.ui.vuetify3 import SinglePageLayout
from trame.widgets import vuetify3 as v3
from trame.decorators import life_cycle


@TrameApp()
class FileInputUploadExample:
    """Demo app to showcase an error being thrown when uploading a file with insufficient permissions."""

    def __init__(self) -> None:
        self.server = get_server(None)

        self.build_ui()

    def build_ui(self) -> None:
        with SinglePageLayout(self.server) as layout:
            with layout.content:
                v3.VFileInput(
                    multiple=True,
                    model_value=("uploaded_files", []),
                    update_modelValue=(self.on_upload_complete, "[$event]"),
                )

    @life_cycle.error
    def on_error(self, message: str) -> None:
        print(f"A JS error occured: {message}")

    def on_upload_complete(
        self, uploaded_files: list[dict[str, str | int | None]]
    ) -> None:
        """A callback normally fired when the upload is complete.

        This will fire if the files have proper permissions, but will not if one of
        the files lacks read permissions for the uploading user. This can be observed
        by seeing a JS Error thrown in the Web console.
        """
        errored_files: list[dict[str, str | int | None]] = []
        successful_files: list[dict[str, str | int | None]] = []

        for uploaded_file in uploaded_files:
            if uploaded_file["error"] is not None:
                errored_files.append(uploaded_file)
            else:
                successful_files.append(uploaded_file)

        print(
            "The following files were uploaded successfully:",
            [file["name"] for file in successful_files],
        )
        print(
            "The following files had errors while uploading:",
            [file["name"] for file in errored_files],
        )

        self.server.state.uploaded_files = successful_files


if __name__ == "__main__":
    app = FileInputUploadExample()
    app.server.start()

Closes #51

Used so files with read errors don't halt execution, instead are handled
gracefully and submitted to the server
@snacksbro snacksbro marked this pull request as ready for review March 19, 2026 20:12
@jourdain
Copy link
Copy Markdown
Collaborator

It would be great to update fileHandler in js-lib too. This seems great!

snacksbro and others added 3 commits March 20, 2026 10:54
Automatically generated by python-semantic-release
This reverts commit 934784c.

Occurred due to Actions running on a remote fork
@snacksbro
Copy link
Copy Markdown
Contributor Author

I accidentally had Actions running on my fork, I think that's what caused 934784c to occur. I've reverted it now

@jourdain
Copy link
Copy Markdown
Collaborator

LGTM

@jourdain jourdain merged commit f330811 into Kitware:master Mar 24, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

JS Error When Uploading Multiple Files If One Has Permission Errors

2 participants