Problem/Motivation

AJAX error when using progress bar on file field widget

An AJAX HTTP error occurred.
HTTP Result Code: 500
<code>

The cause is this:
<code>
Message RuntimeException: Controller "Drupal\file\Controller\FileWidgetAjaxController::progress()" requires that you provide a value for the "$key" argument (because there is no default value or because there is a non optional argument after this one). in Drupal\Core\Controller\ControllerResolver->doGetArguments() (line 171 of /var/www/example.ca/public_html/core/lib/Drupal/Core/Controller/ControllerResolver.php).

Proposed resolution

Indeed FileWidgetAjaxController::progress has a $key argument so

  1. Add the $upload_progress_key to the progress url
  2. Change the routing definition to receive the key

Remaining tasks

Refactor FileWidgetAjaxController::progress so $progress['message'] and $progress['percentage'] appears only once -- the two indexes should be be two variables. Anyways, that's a followup.

User interface changes

The AJAX progress bar begins to work.

API changes

This is not part of the API surface.

Data model changes

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

sailnet created an issue. See original summary.

NickDickinsonWilde’s picture

Version: 8.0.0-rc1 » 8.0.x-dev
Priority: Normal » Major
Status: Active » Needs review
FileSize
1.05 KB

Found this error yesterday, didn't have time to fix it as it was not a blocker for my project stage. Now that I was just polishing figured I should fix it, but might as well use this issue to avoid duplicates.

The problem was that the route wasn't configured to pass the key to the controller.

NickDickinsonWilde’s picture

Issue tags: +rc target triage

This does cause an error on file upload - doesn't actually interfere with the upload but still looks bad, so I think it should get in before the 19th.

cilefen’s picture

Can someone please post the server-side error in the issue summary?

NickDickinsonWilde’s picture

Here's a copy of a log message:
Location http://example.ca/file/progress?_format=json
Referrer http://example.ca/file/add
Message RuntimeException: Controller "Drupal\file\Controller\FileWidgetAjaxController::progress()" requires that you provide a value for the "$key" argument (because there is no default value or because there is a non optional argument after this one). in Drupal\Core\Controller\ControllerResolver->doGetArguments() (line 171 of /var/www/example.ca/public_html/core/lib/Drupal/Core/Controller/ControllerResolver.php).
Severity Error

cilefen’s picture

Issue summary: View changes
chx’s picture

Issue summary: View changes
Status: Needs review » Reviewed & tested by the community
xjm’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: -rc target triage

Thanks for the bug report!

Needs tests probably?

xjm’s picture

Issue tags: +Needs tests
chx’s picture

Needs tests how? Do we have AJAX tests already? Isn't this something after step2 of TNG'ing tests? dawehner is working on getting phantomjs to drupalci.

xjm’s picture

@chx, we have been able to test the server side for AJAX requests and responses for awhile, even though we can't test the JavaScript. See WebTestBase::drupalPostAjaxForm(). Since this is a server-side error, it should indeed be testable I think.

chx’s picture

So you can test path: '/file/progress/{key}' this hunk but not this $element['upload_button']['#ajax']['progress']['url'] = Url::fromRoute('file.ajax_progress', ['key' => $upload_progress_key]); . I guess that's worth a test, sure.

aerozeppelin’s picture

Status: Needs work » Needs review
FileSize
2.1 KB
1.04 KB

Test for '/file/progress/{key}'.

aerozeppelin’s picture

chx’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: -Needs tests
catch’s picture

Status: Reviewed & tested by the community » Needs review
+++ b/core/modules/file/src/Tests/FileFieldWidgetTest.php
@@ -40,7 +40,7 @@ protected function setUp() {
+  public static $modules = array('comment', 'block', 'locale');

Why is locale needed in the test modules?

aerozeppelin’s picture

Why is locale needed in the test modules?

Pardon my ignorance. :D

swentel’s picture

Status: Needs review » Reviewed & tested by the community

Took me a while to get this configured, but yes, this patch fixes the error. I didn't see any real 'progress' though while uploading a 700 MB file, I thought I'd see some message with percentage or so? In the end, the file as uploaded though, so maybe for a follow up ?
Moving to RTBC for feedback from committers.

imre.horjan’s picture

The 'Internal Server Error' is gone, however the progress meter always get a -1 in response using PECL upload progress on PHP 5.6.

I've tested upload progress on the same server with Drupal 7, and it's example from https://github.com/php/pecl-php-uploadprogress/tree/master/examples and both worked.

I think this still needs work. ( I used path #15)

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

#19 implies there is more to do here to make the progress bar work properly here.

swentel’s picture

Hmm yeah, both uploadprogress_get_info() apcu_fetch() return nothing .. looking into it.

We also know there's no upload progress on the testbot, so we can't write a test for it (for now).

imre.horjan’s picture

I'm not sure how this was solved in D7 to handle multiple file upload fields in a single form, but I think we need a hidden input using the same "key" as sent back to the server to track progress:
https://harperreed.com/writing/2007/04/16/pecl-uploadprogress-example/

I have never tried APCu, so don't know how it works.

swentel’s picture

The hidden field is there:

<div id="ajax-wrapper"><input class="file-progress" data-drupal-selector="edit-field-file-0-upload-identifier" type="hidden" name="field_file[0][UPLOAD_IDENTIFIER]" value="1347176024">
<input data-drupal-selector="edit-field-file-0-upload" type="file" id="edit-field-file-0-upload" name="files[field_file_0]" size="22" class="js-form-file form-file">

The code is more or less the same as in D7, so it's probably going to be something trivial.

- edit - works perfect on D7 btw

swentel’s picture

It's not entirely related, but just adding it because there's various problems with file uploads - #2346893: Duplicate AJAX wrapper around a file field

swentel’s picture

swentel’s picture

Issue tags: +JavaScript

Ok, I have a hint why this is failing: compare

D7 post data

------WebKitFormBoundary4d4zgU831PUSggVA
Content-Disposition: form-data; name="UPLOAD_IDENTIFIER"

123487692

with

D8 post data

------WebKitFormBoundaryctCyV2fneyPxBbKl
Content-Disposition: form-data; name="field_file[0][UPLOAD_IDENTIFIER]"

426806279

The name is wrong in the D8 version. file.js tries to rename the name field temporarily (and it finds it), but it doesn't end up in the post data.

swentel’s picture

Status: Needs work » Reviewed & tested by the community

I've split the issue up in #2662932: Fix file upload progress bar, I think it's better to get this one in first because it's

a) an easy and straight bug fix
b) the other one really seems to be a js problem and if we want people to help out, then i'd be easier if the fatal is already in

So therefor, RTBC.

catch’s picture

Status: Reviewed & tested by the community » Fixed

Committed/pushed to 8.1.x and cherry-picked to 8.0.x, thanks!

  • catch committed de27f19 on
    Issue #2587755 by aerozeppelin, NickWilde, swentel: AJAX error when...

  • catch committed 46599bb on
    Issue #2587755 by aerozeppelin, NickWilde, swentel: AJAX error when...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

webservant316’s picture

I am seeing this error with Drupal 7.56 and PHP71. Problem goes away with PHP70. Is there a issue post or fix for Drupal-7.x?

TommyChris’s picture

PHP version 7.2.0RC5 works OK!