Upload field - uncaught exception: Unknown file id

Upload field - uncaught exception: Unknown file id

Andreas PreiningerAndreas Preininger Posts: 3Questions: 0Answers: 0

Hi Allan and community

We have an unusual problem with single-upload-fields.

The main table in the database is called agent_test. It is quite extensive and contains 17 single-upload-fields and 6 multi-upload-fields, among other fields for data collection.

Each single-upload-field is linked to the main table via ->leftJoin.

Each single-upload-field has its own table in the database for the purpose of saving the technical data of each file that is uploaded, like file-name, file-size, system-path and so on.

When a file has been uploaded it arrives at the destination folder on the server, the entry is made in the technical table of the corresponding upload-field and the id of the file is inserted into the main table agent_test in the corresponding column. In most cases this process works without problems and people can continue their work on the table.

However, on some rare occasions something goes wrong.

The "something going wrong" involves the disappearance of the entry made in the technical table of the corresponding upload-field. When this happens, for an unknown reason as of until now, the file id is still present in the main table agent_test but the corresponding entry in the upload-field table is gone, which leads to the main table agent_test to seize functioning and this JavaScript error is produced:

uncaught exception: Unknown file id SO-AND-SO in table SO-AND-SO

It is unclear to me why this happens. As stated, most of the time people have no problem uploading files, but on some rare occasions this situation happens.

The error can happen to any of the single-upload-fields. It is not limited to a specific one out of the 17 existing single-upload-fields.

We have not yet experienced this error with any of the multi-upload-fields.


Here are relevant portions of the code:

JavaScript:

var editor;

$(document).ready(function() {

    editor = new $.fn.dataTable.Editor( {
        ajax: "../php/test.php",
        table: "#tabAGTest",
        i18n: {
        ...
        },

        fields: [

            ...

            {
                label: "WIDVM:",
                name: "agent_test.widvm",
                type: "upload",
                display: function ( file_id ) {
                  return '<span class="file-link pdf"></span>';
                }
            },

            ...

        ]

    } );


    $('#tabAGTest').on( 'click', 'tbody td:not(:first-child,:nth-child(2),:nth-child(3),:nth-child(9))', function (e) {
          editor.bubble( this );
    } );


    var bTable = $('#tabAGTest').DataTable( {

        responsive: true,
        dom: "lBfrtip",
        ajax: "../php/test.php",

        columns: [

          { // Responsive control column
            data: null,
            defaultContent: '',
            className: 'control',
            orderable: false
          },
          { // Checkbox select column
            data: null,
            defaultContent: '',
            className: 'select-checkbox',
            orderable: false
          },

          ...

          {
            data: "agent_test.widvm",
            render: function ( file_id ) {
              return file_id ?
                '<a class="file-link pdf widvm" href="../../getfile.php?docType=widvm&fileID=' + file_id +
                '&agent=test' +
                '&ext='  + editor.file( 'u_test_widvm', file_id ).dend  +
                '&file=' + editor.file( 'u_test_widvm', file_id ).dname +'" target="_blank"></a>' : null;
            },
            defaultContent: ""
          },

          ...

        ],

        order: [ 2, 'asc' ],
        select: {
          style:    'os',
          selector: 'td.select-checkbox'
        },

        buttons: [
            ...
        ],

        language: {
            ...
        }

    } );

} );

And here is the PHP code:

// DataTables PHP library
include( "../../lib/DataTables.php" );


// Alias Editor classes so they are easy to use
use
  DataTables\Editor,
  DataTables\Editor\Field,
  DataTables\Editor\Format,
  DataTables\Editor\Mjoin,
  DataTables\Editor\Options,
  DataTables\Editor\Upload,
  DataTables\Editor\Validate,
  DataTables\Editor\ValidateOptions;


Editor::inst( $db, 'agent_test' )

    ->fields(

        ...

        Field::inst( 'agent_test.widvm' )
          ->upload( Upload::inst( $_SERVER['DOCUMENT_ROOT'].'/../private_html/upload/test/widvm/__ID__-__NAME__' )
            ->db( 'u_test_widvm', 'id', array(
              'dagent'   => 'test',
              'dend'     => Upload::DB_EXTN,
              'dgroese'  => Upload::DB_FILE_SIZE,
              'dname'    => Upload::DB_FILE_NAME,
              'sys_pfad' => Upload::DB_SYSTEM_PATH
            ) )
            ->dbClean( 'agent_test.widvm', function ( $data ) {
              for ( $i=0, $ien=count($data) ; $i<$ien ; $i++ ) {
                if ( is_file( $data[$i]['sys_pfad'] ) )
                  unlink( $data[$i]['sys_pfad'] );
              }

              return true;
            } )

            ->validator( function ( $file ) {
              if ( strlen($file['name']) > 50 ) {
                return "File name should not contain more than 50 characters.";
              }
              return null;
            } )
            ->validator( function ( $file ) {
              if ( $file['size'] >= 1000000 ) {
                return "File size should be smaller than 1MB.";
              }
              return null;
            } )
            ->validator( Validate::fileExtensions(
              array( 'pdf' ),
                'Only PDF files allowed.'
            ) )
          )

          ->setFormatter( Format::ifEmpty( null ) ),

        ...

    )

    ...

    ->leftJoin( 'u_test_widvm',    'u_test_widvm.id',    '=', 'agent_test.widvm' )

    ...

    ->process( $_POST )
    ->json();

Does anyone have an idea what may be causing this problem?

Replies

  • allanallan Posts: 61,083Questions: 1Answers: 9,960 Site admin

    What version of Editor (JS and PHP) are you using? I think this was a problem previously that was fixed in 1.9 when you attempt to use the same files table for different files. It was effectively overwriting them - specifically this commit fixed it.

    Allan

  • Andreas PreiningerAndreas Preininger Posts: 3Questions: 0Answers: 0

    These are the versions:

    DataTables Editor version is: v1.9.0

    jQuery version is: v3.4.0

    PHP version on the server is: v7.1.29


    As I stated above, each single-upload-field has its own files table in the database, to avoid conflicts if something goes wrong. But unfortunately sometimes something does go wrong and I still don't know why.

    I know about the commit at GitHub to which you link to. I found the corresponding discussion in this forums in the past and also used the fix which you provided. At that time I thought the problem is solved. Then came version 1.9 and the fix was included. But unfortunately on some rare occasions the users find themselves in that situation again and the main table stops working.

    At one point I thought that maybe this error occurs when the saving of the form is delayed. For example, the user uploads one or two files into the form, does not save yet, gets a phone call and spends the next twenty or so minutes on the phone, then comes back and finally saves the form. At one point I thought that if such a delay occurs, maybe DataTables removes the already made entry from the files table in the database. But I tested this myself and everything works as it should, even if I delay the saving of the form for 25 minutes or so.

    This error has not happened to me, therefore I don't know how to reproduce it. On rare occasions it happens to the users who work on the tables all the time. It's not limited to a specific single-upload-field, it can be any one of them.

    In order to produce the error I go to the database and manually remove the already made entry in the files table to cause the JavaScript exception error.

    I'd like to catch this error when it happens and display an icon or a message that something went wrong with the upload, so the user can upload the file again. But more importantly, the main table should not crash because of the missing entry in the files table of the upload field.

    What would be the best way to catch this error?

    Should it be done in PHP on the server side or in JavaScript on the client side?

  • allanallan Posts: 61,083Questions: 1Answers: 9,960 Site admin

    Thanks for the extra details. How interesting. Is it possible the user is using two different browser sessions? That's the only other way I can think of this error occurring based on your description. Although that would be a bit odd.

    To catch the error, wrap the file() method in a try / catch:

    try {
      var fileInto = editor.field( ... );
      return <a href="..."...>;
    }
    catch (e) {
      alert( 'Upload error' );
    }
    

    Allan

  • Andreas PreiningerAndreas Preininger Posts: 3Questions: 0Answers: 0

    Thank you Allan, I will try that the next time I work on the tables.

    Concerning "different browser sessions"...

    After login the browser session is active as long as the browser is open. I don't know if the browser settings of the users may interfere for whatever reason. Or maybe the generating of the browser session needs to be improved. That's one thing I can look into.

    At one time I thought that maybe when two users work simultaneously on the same table, that this would cause the problem. But it was not so, it happened even when just one user worked on it.

    If I find out that it's related to the browser session I'll post another reply here explaining the issue.

    Thank you for your help.

This discussion has been closed.