<p>Rather than throwing an exception when the filesize is too large, you should be adding a validation error, which should be handled correctly.</p>
<pre class="lang-php prettyprint-override"><code>use craft\base\Model;
use craft\elements\Asset;
use craft\events\DefineRulesEvent;
use craft\helpers\ArrayHelper;
use yii\base\Event;

Event::on(
    Asset::class,
    Model::EVENT_DEFINE_RULES,
    function(DefineRulesEvent $event) {
        /** @var Asset $asset */
        $asset = $event-&gt;sender;

        $event-&gt;rules[] = ['tempFilePath', function(string $attribute) use ($asset) {
            if (!$asset-&gt;volumeId) {
                return;
            }

            // Get the volume
            $volume = Craft::$app-&gt;volumes-&gt;getVolumeById($asset-&gt;volumeId);
            // Get the settings global set
            $settings = Craft::$app-&gt;globals-&gt;getSetByHandle('imageSizeLimits');
            // See if we have a size limit for this volume
            $volumeSettings = ArrayHelper::firstWhere($settings-&gt;assetVolumes ?? [], 'volumeHandle', $volume-&gt;handle);
            if (empty($volumeSettings['sizeLimit'])) {
                return;
            }

            // Make sure the asset is within the allowed file size
            $fileSize = filesize($asset-&gt;tempFilePath);
            if ($fileSize &gt; $volumeSettings['sizeLimit']) {
                $formattedSizeLimit = Craft::$app-&gt;formatter-&gt;asShortSize($volumeSettings['sizeLimit'], false);
                $asset-&gt;addError($attribute, &quot;$asset-&gt;filename exceeds $formattedSizeLimit&quot;);
            }
        }];
    }
);
</code></pre>

CC BY-SA 4.0
2021-09-01T18:57:50.940Z
no luck! Have any other suggestions?
berrydev
CC BY-SA 4.0
2021-09-13T19:28:33.607Z
@berrydev Can you elaborate? Maybe write into support@craftcms.com with your Composer files and full module code, and we can work with you from there.
Brandon Kelly
CC BY-SA 4.0
2021-08-30T18:44:39.080Z
2021-08-30T18:44:39.080Z
Brandon Kelly
<p>I wrote the following code in <code>Module.php</code> that checks if a file size is too large during an asset upload (the file size limit and asset volume handles are defined in a globals: a table with one column the volume handle and the other column the size limit in bytes)</p>
<pre><code>/* image file size limit */
        Event::on(
            Asset::class,
            Element::EVENT_BEFORE_SAVE,
            function(ModelEvent $modelEvent){
              $model = $modelEvent-&gt;sender;
              if(isset($model-&gt;volumeId) &amp;&amp; !empty($model-&gt;volumeId)) {
                // Get the image
                $volume = Craft::$app-&gt;volumes-&gt;getVolumeById($model-&gt;volumeId);
                // Get the settings global set
                $settings = Craft::$app-&gt;globals-&gt;getSetByHandle('imageSizeLimits');
                $tmpPath = $model-&gt;tempFilePath;
                $fileSize = filesize($tmpPath);
                if( (!empty($settings-&gt;assetVolumes)) &amp;&amp; (isset($settings-&gt;assetVolumes)) ) {
                  foreach($settings-&gt;assetVolumes as $row) {
                    $volumeHandle = $row['volumeHandle'];
                    $sizeLimit = $row['sizeLimit'];
                    if( (!empty($sizeLimit)) &amp;&amp; (isset($sizeLimit)) &amp;&amp; (!empty($volumeHandle)) &amp;&amp; (isset($volumeHandle)) ) {
                      // Check if the volume should have a size limit
                      if($volume-&gt;handle == $volumeHandle){
                        if($fileSize &gt; $sizeLimit){
                          $imgName = $model-&gt;filename;
                          if($sizeLimit &gt;= 1000000) {
                            $limit = floor($sizeLimit/1000000); //limit in MB
                            throw new VolumeException(&quot;{$imgName} exceeds {$limit} MB limit&quot;);
                            return false;
                          } else {
                            $limit = floor($sizeLimit/1000); //limit in MB
                            throw new VolumeException(&quot;{$imgName} exceeds {$limit} KB limit&quot;);
                            return false;
                          }
                        }
                      }
                    }
                  }
                }
              }
              return;
            }
        );
        /* end image file size limit */
</code></pre>
<p>When uploading an asset to an entry where the asset exceeds the file size limit, the exception is thrown and an alert box appears, which is expected. But once the 'OK' button is clicked, the upload bar stays and you can no longer try to upload anything else. (screenshot below)
<a href="https://i.sstatic.net/ZAJ93.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/ZAJ93.png" alt="screenshot of upload bar" /></a>
How to I stop the upload from hanging when an exception is thrown?</p>

<events><modules><assets-field>
Asset upload hangs when uploading to asset field in entry
# Asset upload hangs when uploading to asset field in entry

(Asked by: username_0 on 2021-08-26)

I wrote the following code in Module.php that checks if a file size is too large during an asset upload (the file size limit and asset volume handles are defined in a globals: a table with one column the volume handle and the other column the size limit in bytes)
/* image file size limit */
        Event::on(
            Asset::class,
            Element::EVENT_BEFORE_SAVE,
            function(ModelEvent $modelEvent){
              $model = $modelEvent->sender;
              if(isset($model->volumeId) && !empty($model->volumeId)) {
                // Get the image
                $volume = Craft::$app->volumes->getVolumeById($model->volumeId);
                // Get the settings global set
                $settings = Craft::$app->globals->getSetByHandle('imageSizeLimits');
                $tmpPath = $model->tempFilePath;
                $fileSize = filesize($tmpPath);
                if( (!empty($settings->assetVolumes)) && (isset($settings->assetVolumes)) ) {
                  foreach($settings->assetVolumes as $row) {
                    $volumeHandle = $row['volumeHandle'];
                    $sizeLimit = $row['sizeLimit'];
                    if( (!empty($sizeLimit)) && (isset($sizeLimit)) && (!empty($volumeHandle)) && (isset($volumeHandle)) ) {
                      // Check if the volume should have a size limit
                      if($volume->handle == $volumeHandle){
                        if($fileSize > $sizeLimit){
                          $imgName = $model->filename;
                          if($sizeLimit >= 1000000) {
                            $limit = floor($sizeLimit/1000000); //limit in MB
                            throw new VolumeException("{$imgName} exceeds {$limit} MB limit");
                            return false;
                          } else {
                            $limit = floor($sizeLimit/1000); //limit in MB
                            throw new VolumeException("{$imgName} exceeds {$limit} KB limit");
                            return false;
                          }
                        }
                      }
                    }
                  }
                }
              }
              return;
            }
        );
        /* end image file size limit */

When uploading an asset to an entry where the asset exceeds the file size limit, the exception is thrown and an alert box appears, which is expected. But once the 'OK' button is clicked, the upload bar stays and you can no longer try to upload anything else. (screenshot below)

How to I stop the upload from hanging when an exception is thrown?

**Tags:** events, modules, assets-field

---

## 1 answers

### Answer by username_1 on 2021-08-30. Score: 2

Rather than throwing an exception when the filesize is too large, you should be adding a validation error, which should be handled correctly.
use craft\base\Model;
use craft\elements\Asset;
use craft\events\DefineRulesEvent;
use craft\helpers\ArrayHelper;
use yii\base\Event;

Event::on(
    Asset::class,
    Model::EVENT_DEFINE_RULES,
    function(DefineRulesEvent $event) {
        /** @var Asset $asset */
        $asset = $event->sender;

        $event->rules[] = ['tempFilePath', function(string $attribute) use ($asset) {
            if (!$asset->volumeId) {
                return;
            }

            // Get the volume
            $volume = Craft::$app->volumes->getVolumeById($asset->volumeId);
            // Get the settings global set
            $settings = Craft::$app->globals->getSetByHandle('imageSizeLimits');
            // See if we have a size limit for this volume
            $volumeSettings = ArrayHelper::firstWhere($settings->assetVolumes ?? [], 'volumeHandle', $volume->handle);
            if (empty($volumeSettings['sizeLimit'])) {
                return;
            }

            // Make sure the asset is within the allowed file size
            $fileSize = filesize($asset->tempFilePath);
            if ($fileSize > $volumeSettings['sizeLimit']) {
                $formattedSizeLimit = Craft::$app->formatter->asShortSize($volumeSettings['sizeLimit'], false);
                $asset->addError($attribute, "$asset->filename exceeds $formattedSizeLimit");
            }
        }];
    }
);

> **Comments:**
> **username_0**: no luck! Have any other suggestions?  
> **username_1**: @berrydev Can you elaborate? Maybe write into support@craftcms.com with your Composer files and full module code, and we can work with you from there.  

---

