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

Submission Error: Maximum execution time of 30 seconds exceeded #1783

Open
vonscriptor opened this issue Feb 6, 2025 · 17 comments
Open

Submission Error: Maximum execution time of 30 seconds exceeded #1783

vonscriptor opened this issue Feb 6, 2025 · 17 comments
Assignees
Labels
investigating Currently investigating the report

Comments

@vonscriptor
Copy link

What happened?

When submitting a form it times out with the error: Maximum execution time of 30 seconds exceeded.

This started occurring after an update from v5.8.7 to v5.9.7.

Errors and Stack Trace (if available)

PHP Warning:  Uncaught ReflectionException: Solspace\Freeform\Attributes\Property\Middleware is not an interface in /Users/[redacted]/Sites/[redacted]/vendor/solspace/craft-freeform/packages/plugin/src/Library/Helpers/ReflectionHelper.php:25

PHP Fatal error:  Maximum execution time of 30 seconds exceeded in /Users/[redacted]/Sites/[redacted]/vendor/solspace/craft-freeform/packages/plugin/src/Library/Helpers/ReflectionHelper.php on line 26

How can we reproduce this?

I'm not really sure how to reproduce this.

  1. My form uses: text, textarea, checkbox, dropdown, signature, and file drag and drop
  2. It uses an Admin Notification
  3. It uses rules to hide/show fields based on a dropdown value(s)
  4. It uses reCAPTCHA
  5. It does not use AJAX

Freeform Edition

Pro

Freeform Version

5.9.7

Craft Version

Pro 5.6.5.1

When did this issue start?

After upgrading from older Freeform version

Previous Freeform Version

5.8.7

@vonscriptor
Copy link
Author

This is happening on more than one project when upgraded to 5.9.7 from a prior version.

@kjmartens kjmartens self-assigned this Feb 6, 2025
@kjmartens kjmartens added the investigating Currently investigating the report label Feb 6, 2025
@kjmartens
Copy link
Contributor

I'm very sorry for the trouble you're experiencing @vonscriptor,

I cannot duplicate this issue and haven't heard of this being reported yet.

Would you be able to provide the following? 🙂

  1. A screenshot of your Freeform Diagnostics page.
  2. A screenshot of the form in the layout tab of the builder. If anything is sensitive, you can blur some parts.
  3. A list of which integrations are being used in this form (or screenshot of the Integrations tab in the builder).

Thanks!

@vonscriptor
Copy link
Author

vonscriptor commented Feb 6, 2025

Just to reiterate this happened on 2 of my projects that I just attempted to update Freeform on. One uses Freeform Pro, the other uses Express. Both updated from the same versions (5.8.7). Both timed out, huge stack trace gets output, ends up slowing down my server(s) for a bit after the timeout even.

Image

Image

No integrations on the simple Express project.

@vonscriptor
Copy link
Author

Sorry forgot to mention… those are screenshots after downgrading Freeform back to v5.8.7. Thought it'd still be what you're looking for.

@kjmartens
Copy link
Contributor

Thanks @vonscriptor,

I am having a developer check into this shortly. 🙂

@kjmartens kjmartens added confirmed Bug has been confirmed fixing Currently working in a fix for the issue and removed investigating Currently investigating the report labels Feb 6, 2025
@kjmartens
Copy link
Contributor

This should now be resolved in Freeform 5.9.8+ 🙂

@kjmartens kjmartens added resolved Issue has been resolved and removed fixing Currently working in a fix for the issue labels Feb 6, 2025
@vonscriptor
Copy link
Author

Unfortunately, this is still occurring for me.

Here are some of the errors I'm seeing on forms that have the issue:

[06-Feb-2025 22:51:58 America/Detroit] PHP Fatal error: Maximum execution time of 30 seconds exceeded in /Users/[redacted]/Sites/[redacted]/vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php on line 44

[06-Feb-2025 22:58:57 America/Detroit] PHP Fatal error: Maximum execution time of 30 seconds exceeded in /Users/[redacted]/Sites/[redacted]/vendor/voku/stringy/src/Stringy.php on line 108

[06-Feb-2025 23:02:00 America/Detroit] PHP Fatal error: Maximum execution time of 30 seconds exceeded in /Users/[redacted]/Sites/[redacted]/vendor/yiisoft/yii2/db/Command.php on line 1331

[06-Feb-2025 23:08:45 America/Detroit] PHP Fatal error: Maximum execution time of 30 seconds exceeded in /Users/[redacted]/Sites/[redacted]/vendor/symfony/finder/Iterator/DepthRangeFilterIterator.php on line 46

Image

"It looks like there was an issue verifying your sign-up."

@kjmartens kjmartens added investigating Currently investigating the report and removed confirmed Bug has been confirmed resolved Issue has been resolved labels Feb 7, 2025
@kjmartens kjmartens reopened this Feb 7, 2025
@kjmartens
Copy link
Contributor

Looks like maybe your environment isn't liking a number of files. We'll check into this again shortly.

@kjmartens
Copy link
Contributor

Reviewing this again, I see that the files you reference are not part of Freeform. Can you share the full stack trace of the error you get to see where/if Freeform is causing the issue? 🙂

Thanks!

@vonscriptor
Copy link
Author

The only way I'm able to get a Freeform submission to work is by disabling "Store Submitted Data for this Form". The Notifications will work as normal.

I tried creating a new form with one default text field and a submit button, AJAX / no AJAX, no notifications, no rules, no integrations. Disabling "Store Submitted Data for this Form" was the only way for me to get around the timeout.

The timeout is inconsistent in what it reports. My uninformed guess would be because when Freeform tries to store the submission in the database it's causing Craft to attempt things over and over until it the timeout and the stack trace is just where it was in the process at that moment. Here are 2 times in my testing just now that showed a stack trace with Freeform:

  1. HashHelper.php on line 66
  2. SessionContext.php on line 198

Hopefully this is helpful! Let me know what else I can do. Thanks!

@kjmartens
Copy link
Contributor

Thanks @vonscriptor.

However, would you be able to copy and paste the entire thing? 🙂

@vonscriptor
Copy link
Author

Just sent a support email. When you reply I can attach a bunch of screenshots for reference.

@seandelaney
Copy link
Contributor

@vonscriptor

Can you share the contents of /dist/js/freeform-recaptcha_v3.js file please? Relpace recaptcha key/secret with XXX or something.

@seandelaney
Copy link
Contributor

@vonscriptor

Can you edit this file locally:

https://github.com/solspace/craft-freeform/blob/v5/packages/plugin/src/Library/Helpers/AttributeHelper.php

Just before line #19, add var_dump($attribute);die();

Tell me what outputs please? I want to see what $attribute is coming back as?

@vonscriptor
Copy link
Author

@seandelaney I do have /web/dist/js/freeform-recaptcha_v3.js (and a .js.gz), but is this being used?

!function(){"use strict";var e,r,n,t,o={5784:function(e,r,n){n.d(r,{ZO:function(){return l},_V:function(){return u},zi:function(){return m}});var t,o,a,i=n(5595);!function(e){e.DARK="dark",e.LIGHT="light"}(o||(o={})),function(e){e.COMPACT="compact",e.NORMAL="normal"}(a||(a={})),window.freeform||(window.freeform={}),(null===(t=window.freeform)||void 0===t?void 0:t.captchas)||(window.freeform.captchas={loaders:new Map,listeners:new WeakSet,loaderPromises:new Map});var f,s=function(e,r){return r.querySelector('[data-captcha="'.concat(e,'"]'))},c=function(e){return{sitekey:e.dataset.siteKey||"",theme:e.dataset.theme||o.LIGHT,size:e.dataset.size||a.NORMAL,version:e.dataset.version,lazyLoad:void 0!==e.dataset.lazyLoad,action:e.dataset.action||"submit",locale:e.dataset.locale}},d="recaptcha";!function(e){e.V2_CHECKBOX="v2-checkbox",e.V2_INVISIBLE="v2-invisible",e.V3="v3"}(f||(f={}));var u=function(e,r){var n=l(e);if(!n)return Promise.resolve();var t=m(n),o=t.version,a=t.sitekey,u=t.locale,p=new URL("https://www.google.com/recaptcha/api.js");return o===f.V3?p.searchParams.append("render",a):p.searchParams.append("render","explicit"),u&&p.searchParams.append("hl",u),function(e,r,n,t){var o=s(r,n);if(o){var a,f=window.freeform.captchas,d=f.listeners,u=f.loaderPromises,l=f.loaders,m=c(o),p=m.lazyLoad,v=void 0!==p&&p,h=m.version,w=void 0===h?"default":h,b=v&&!t,y="".concat(r,"-").concat(w);u.has(y)?a=u.get(y):(a=new Promise((function(r,n){l.set(y,(function(){(function(e){return new Promise((function(r,n){var t=String(e);if(!document.getElementById(t)){var o=document.createElement("script");o.src=String(e),o.async=!0,o.defer=!0,o.id=t,o.addEventListener("load",(function(){return r()})),o.addEventListener("error",(function(){return n(new Error("Error loading script ".concat(e)))})),document.body.appendChild(o)}}))})(e).then(r).catch(n)}))})),u.set(y,a));var g=l.get(y);return b?d.has(n)||((0,i.oW)(n,["input","submit"],g,{once:!0}),d.add(n)):g(),a}}(p,d,e,r)},l=function(e){return s(d,e)},m=function(e){return c(e)}},5595:function(e,r,n){n.d(r,{oW:function(){return t}});var t=function(e,r,n,t){o("add",{elements:e,type:r,callback:n,options:t})},o=function(e,r){var n=r.type,t=r.elements,o=r.callback,a=r.options,i=Array.isArray(n)?n:[n],f=Array.isArray(t)?t:[t];Array.from(f).forEach((function(r){i.forEach((function(n){"add"===e?r.addEventListener(n,o,a):r.removeEventListener(n,o,a)}))}))}}},a={};function i(e){var r=a[e];if(void 0!==r)return r.exports;var n=a[e]={exports:{}};return o[e](n,n.exports,i),n.exports}i.d=function(e,r){for(var n in r)i.o(r,n)&&!i.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:r[n]})},i.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},e={form:{ready:"freeform-ready",reset:"freeform-on-reset",submit:"freeform-on-submit",removeMessages:"freeform-remove-messages",fieldRemoveMessages:"freeform-remove-field-messages",renderSuccess:"freeform-render-success",renderFieldErrors:"freeform-render-field-errors",renderFormErrors:"freeform-render-form-errors",ajaxBeforeSuccess:"freeform-before-ajax-success",ajaxSuccess:"freeform-ajax-success",ajaxError:"freeform-ajax-error",ajaxBeforeSubmit:"freeform-ajax-before-submit",ajaxAfterSubmit:"freeform-ajax-after-submit",afterFailedSubmit:"freeform-after-failed-submit",handleActions:"freeform-handle-actions"},rules:{applied:"freeform-rules-applied"},table:{onAddRow:"freeform-field-table-on-add-row",afterRowAdded:"freeform-field-table-after-row-added",onRemoveRow:"freeform-field-table-on-remove-row",afterRemoveRow:"freeform-field-table-after-remove-row"},dragAndDrop:{renderPreview:"freeform-field-dnd-on-render-preview",renderPreviewRemoveButton:"freeform-field-dnd-on-render-preview-remove-button",renderErrorContainer:"freeform-field-dnd-render-error-container",showGlobalMessage:"freeform-field-dnd-show-global-message",appendErrors:"freeform-field-dnd-append-errors",clearErrors:"freeform-field-dnd-clear-errors",onChange:"freeform-field-dnd-on-change",onUploadProgress:"freeform-field-dnd-on-upload-progress"},saveAndContinue:{saveFormhandleToken:"freeform-save-form-handle-token"}},r=i(5784),n=function(e,r,n,t){return new(n||(n=Promise))((function(o,a){function i(e){try{s(t.next(e))}catch(e){a(e)}}function f(e){try{s(t.throw(e))}catch(e){a(e)}}function s(e){var r;e.done?o(e.value):(r=e.value,r instanceof n?r:new n((function(e){e(r)}))).then(i,f)}s((t=t.apply(e,r||[])).next())}))},t=function(e,r){var n,t,o,a,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:f(0),throw:f(1),return:f(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function f(f){return function(s){return function(f){if(n)throw new TypeError("Generator is already executing.");for(;a&&(a=0,f[0]&&(i=0)),i;)try{if(n=1,t&&(o=2&f[0]?t.return:f[0]?t.throw||((o=t.return)&&o.call(t),0):t.next)&&!(o=o.call(t,f[1])).done)return o;switch(t=0,o&&(f=[2&f[0],o.value]),f[0]){case 0:case 1:o=f;break;case 4:return i.label++,{value:f[1],done:!1};case 5:i.label++,t=f[1],f=[0];continue;case 7:f=i.ops.pop(),i.trys.pop();continue;default:if(!((o=(o=i.trys).length>0&&o[o.length-1])||6!==f[0]&&2!==f[0])){i=0;continue}if(3===f[0]&&(!o||f[1]>o[0]&&f[1]<o[3])){i.label=f[1];break}if(6===f[0]&&i.label<o[1]){i.label=o[1],o=f;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(f);break}o[2]&&i.ops.pop(),i.trys.pop();continue}f=r.call(e,i)}catch(e){f=[6,e],t=0}finally{n=o=0}if(5&f[0])throw f[1];return{value:f[0]?f[1]:void 0,done:!0}}([f,s])}}},document.addEventListener(e.form.ready,(function(e){(0,r._V)(e.form)})),document.addEventListener(e.form.submit,(function(e){e.addCallback((function(){return n(void 0,void 0,void 0,(function(){var o,a,i,f,s;return t(this,(function(c){switch(c.label){case 0:return(o=(0,r.ZO)(e.form))?(a=function(e){var n=(0,r.ZO)(e.form);if(!n)return null;var t=n.querySelector("[data-recaptcha]");return t||((t=document.createElement("textarea")).dataset.recaptcha="",t.name="g-recaptcha-response",t.style.visibility="hidden",t.style.position="absolute",t.style.top="-9999px",t.style.left="-9999px",t.style.width="1px",t.style.height="1px",t.style.overflow="hidden",t.style.border="none",n.appendChild(t)),t}(e),!a||e.isBackButtonPressed?[2]:[4,(0,r._V)(e.form,!0)]):[2,null];case 1:return c.sent(),i=(0,r.zi)(o),f=i.sitekey,s=i.action,[4,new Promise((function(e){grecaptcha.ready((function(){return n(void 0,void 0,void 0,(function(){var r;return t(this,(function(n){switch(n.label){case 0:return[4,grecaptcha.execute(f,{action:s})];case 1:return r=n.sent(),a.value=r,e(),[2]}}))}))}))}))];case 2:return[2,c.sent()]}}))}))}))}))}();

When adding var_dump($attribute);die(); to /vendor/solspace/craft-freeform/packages/plugin/src/Library/Helpers/AttributeHelper.php before line 19 it outputs:
object(ReflectionAttribute)#271 (0) { }

If I put it before the foreach and output the $attributes is outputs: array(3) { [0]=> object(ReflectionAttribute)#271 (0) { } [1]=> object(ReflectionAttribute)#272 (0) { } [2]=> object(ReflectionAttribute)#273 (0) { } }

@seandelaney
Copy link
Contributor

@vonscriptor Is this for a form that is causing max timeout errors?

I want to try and catch what the $attributes are when the error triggers.

@vonscriptor
Copy link
Author

@seandelaney

Two things for you…

  1. If I remove the die(); and load the page with the form it outputs:
    (I used AI to redact the file paths.)
An Error occurred while handling another error:
yii\web\HeadersAlreadySentException: Headers already sent in [REDACTED_PATH]/AttributeHelper.php on line 19. 
in [REDACTED_PATH]/Response.php:369
Stack trace:
#0 [REDACTED_PATH]/Response.php(342): yii\web\Response->sendHeaders()
#1 [REDACTED_PATH]/ErrorHandler.php(136): yii\web\Response->send()
#2 [REDACTED_PATH]/ErrorHandler.php(226): yii\web\ErrorHandler->renderException(Object(yii\base\ErrorException))
#3 [REDACTED_PATH]/ErrorHandler.php(152): craft\web\ErrorHandler->renderException(Object(yii\base\ErrorException))
#4 [REDACTED_PATH]/ErrorHandler.php(102): yii\base\ErrorHandler->handleException(Object(yii\base\ErrorException))
#5 [internal function]: craft\web\ErrorHandler->handleException(Object(yii\base\ErrorException))
#6 {main}

Previous exception:
yii\base\ErrorException: session_name(): Session name cannot be changed after headers have already been sent 
in [REDACTED_PATH]/Session.php:357
Stack trace:
#0 [REDACTED_PATH]/ErrorHandler.php(115): yii\base\ErrorHandler->handleError(2, 'session_name():...', '[REDACTED_PATH]', 357)
#1 [internal function]: craft\web\ErrorHandler->handleError(2, 'session_name():...', '[REDACTED_PATH]', 357)
#2 [REDACTED_PATH]/Session.php(357): session_name('CraftSessionId')
#3 [REDACTED_PATH]/Component.php(180): yii\web\Session->setName('CraftSessionId')
#4 [REDACTED_PATH]/BaseYii.php(557): yii\base\Component->__set('name', 'CraftSessionId')
#5 [REDACTED_PATH]/BaseObject.php(107): yii\BaseYii::configure(Object(craft\web\Session), Array)
#6 [internal function]: yii\base\BaseObject->__construct(Array)
#7 [REDACTED_PATH]/Container.php(419): ReflectionClass->newInstanceArgs(Array)
#8 [REDACTED_PATH]/Container.php(170): yii\di\Container->build('craft\\web\\Sessi...', Array, Array)
#9 [REDACTED_PATH]/BaseYii.php(365): yii\di\Container->get('craft\\web\\Sessi...', Array, Array)
#10 [REDACTED_PATH]/Craft.php(71): yii\BaseYii::createObject(Array, Array)
#11 [REDACTED_PATH]/app.web.php(30): Craft::createObject(Array)
#12 [internal function]: {closure}()
#13 [REDACTED_PATH]/Container.php(633): call_user_func_array(Object(Closure), Array)
#14 [REDACTED_PATH]/BaseYii.php(349): yii\di\Container->invoke(Object(Closure), Array)
#15 [REDACTED_PATH]/ServiceLocator.php(137): yii\BaseYii::createObject(Object(Closure))
#16 [REDACTED_PATH]/Module.php(766): yii\di\ServiceLocator->get('session', true)
#17 [REDACTED_PATH]/Application.php(380): yii\base\Module->get('session', true)
#18 [REDACTED_PATH]/Application.php(178): craft\web\Application->get('session')
#19 [REDACTED_PATH]/Session.php(112): yii\web\Application->getSession()
#20 [REDACTED_PATH]/Session.php(133): craft\helpers\Session::session()
#21 [REDACTED_PATH]/Session.php(92): craft\helpers\Session::exists()
#22 [REDACTED_PATH]/User.php(528): craft\helpers\Session::has('__duration')
#23 [REDACTED_PATH]/User.php(199): craft\web\User->renewAuthStatus()
#24 [REDACTED_PATH]/Upvote.php(100): yii\web\User->getIdentity()
#25 [internal function]: doublesecretagency\upvote\Upvote->doublesecretagency\upvote\{closure}(Object(yii\base\Event))
#26 [REDACTED_PATH]/Component.php(641): call_user_func(Object(Closure), Object(yii\base\Event))
#27 [REDACTED_PATH]/ApplicationTrait.php(547): yii\base\Component->trigger('init', Object(yii\base\Event))
#28 [REDACTED_PATH]/ApplicationTrait.php(1633): craft\web\Application->trigger('init')
#29 [REDACTED_PATH]/Application.php(110): craft\web\Application->_postInit()
#30 [REDACTED_PATH]/BaseObject.php(109): craft\web\Application->init()
#31 [REDACTED_PATH]/Application.php(204): yii\base\BaseObject->__construct(Array)
#32 [internal function]: yii\base\Application->__construct(Array)
#33 [REDACTED_PATH]/Container.php(419): ReflectionClass->newInstanceArgs(Array)
#34 [REDACTED_PATH]/Container.php(170): yii\di\Container->build('craft\\web\\Appli...', Array, Array)
#35 [REDACTED_PATH]/BaseYii.php(365): yii\di\Container->get('craft\\web\\Appli...', Array, Array)
#36 [REDACTED_PATH]/Craft.php(71): yii\BaseYii::createObject(Array, Array)
#37 [REDACTED_PATH]/bootstrap.php(343): Craft::createObject(Array)
#38 [REDACTED_PATH]/web.php(40): require('[REDACTED_PATH]')
#39 [REDACTED_PATH]/index.php(11): require('[REDACTED_PATH]')
#40 [REDACTED_PATH]/server.php(110): require('[REDACTED_PATH]')
#41 {main}
  1. When I add the var_dump in it just outputs that rather then rendering the page. If I load the page without it then add the var_dump in the AttributeHelper.php then submit the form here is what is shown in the console…

$attributes dump:
Image

$attribute from within the foreach dump
Image

Let me know what else I can test. I'd be happy to hop on a screenshare as I think that could be much more proficient.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
investigating Currently investigating the report
Development

No branches or pull requests

4 participants