Answers.Body: <p>Looks like you're causing an endless loop there. You're calling <code>Elements::saveElement</code> from <em>within</em> the <code>beforeSave</code> event. This will cause another save event, which will trigger your hook again, which will cause another save event, and so on. This will cause the PHP process to fail, so you get a 502 from the server.</p>
  <blockquote>
  <p>This fails with the 502 error. But if I just change the 4th line to <code>if ($entry-&gt;typeId == '19' &amp;&amp; !$entry-&gt;expiryDate) {</code> it works ok.</p>
  </blockquote>
  <p>With this adjustment, you've prevented the recursive loop, because you're only calling <code>Elements::saveElement</code> once. The second iteration will not cause an additional save, because at that point, the entry has an <code>expiryDate</code>.</p>
  <p>It's still inefficient because this causes the element to be saved twice instead of once.</p>
  <blockquote>
  <p>Can anyone help me learn why that would be? I specifically want to update the dates if <code>eventDate</code> has changed, so I figured I'd just reapply it everytime. Maybe that's too intensive?</p>
  </blockquote>
  <p>You can figure out what native attributes and custom fields have changed using <a href="https://docs.craftcms.com/api/v3/craft-base-element.html#method-getmodifiedattributes" rel="nofollow noreferrer"><code>Element::getModifiedAttributes</code></a> and <a href="https://docs.craftcms.com/api/v3/craft-base-element.html#method-getmodifiedfields" rel="nofollow noreferrer"><code>Element::getModifiedFields</code></a>, but it's much easier and less error-prone to just set the expiry date every time.</p>
  <p>The key is to leave out the call to <code>Craft::$app-&gt;elements-&gt;saveElement($entry);</code>. You're already in the <code>EVENT_BEFORE_SAVE</code> hook, so the element will be saved after your hook has run. So any changes you make to the element will persist automatically.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-10-14T13:30:15.750Z
Answers.Text: Oh wow, I never even considered it was saving twice...but that makes total sense. Thanks for the detailed explanation!
Answers.UserDisplayName: supazu
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-10-27T16:21:04.100Z
Answers.Text: This bit is most relevant - that's really the issue. 
  "The key is to leave out the call to Craft::$app->elements->saveElement($entry);. You're already in the EVENT_BEFORE_SAVE hook, so the element will be saved after your hook has run. So any changes you make to the element will persist automatically."
  I missed it first reading, good work @MoritzLost.
Answers.UserDisplayName: Wallace
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-10-14T07:55:49.697Z
Answers.LastActivityDate: 2022-10-14T07:55:49.697Z
Answers.UserDisplayName: MoritzLost
Body: <p>I'm guessing I'm doing something bad with my code and it's bringing down the server. Here is the full code:</p>
  <pre><code>Event::on(Element::class, Element::EVENT_BEFORE_SAVE, function (ModelEvent $event) {
      if ($event-&gt;sender instanceof craft\elements\Entry) {
          $entry = $event-&gt;sender;
          if ($entry-&gt;typeId == '19') {
              $entry-&gt;expiryDate = $entry-&gt;eventDate-&gt;modify('+1 day');
              Craft::$app-&gt;elements-&gt;saveElement($entry);
          }
      }
  });
  </code></pre>
  <p>This fails with the 502 error. But if I just change the 4th line to <code>if ($entry-&gt;typeId == '19' &amp;&amp; !$entry-&gt;expiryDate) {</code> it works ok.</p>
  <p>Can anyone help me learn why that would be? I specifically want to update the dates if <code>eventDate</code> has changed, so I figured I'd just reapply it everytime. Maybe that's too intensive?</p>
  
Tags: <modules>
Title: 502 Bad Gateway when updating expiry date via module
ThreadText: # 502 Bad Gateway when updating expiry date via module
  
  (Asked by: username_0 on 2022-10-14)
  
  I'm guessing I'm doing something bad with my code and it's bringing down the server. Here is the full code:
  
  ```
  Event::on(Element::class, Element::EVENT_BEFORE_SAVE, function (ModelEvent $event) {
      if ($event->sender instanceof craft\elements\Entry) {
          $entry = $event->sender;
          if ($entry->typeId == '19') {
              $entry->expiryDate = $entry->eventDate->modify('+1 day');
              Craft::$app->elements->saveElement($entry);
          }
      }
  });
  
  ```
  
  This fails with the 502 error. But if I just change the 4th line to `if ($entry->typeId == '19' && !$entry->expiryDate) {` it works ok.
  
  Can anyone help me learn why that would be? I specifically want to update the dates if `eventDate` has changed, so I figured I'd just reapply it everytime. Maybe that's too intensive?
  
  **Tags:** modules
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2022-10-14. Score: 3 | Accepted answer
  
  Looks like you're causing an endless loop there. You're calling `Elements::saveElement` from *within* the `beforeSave` event. This will cause another save event, which will trigger your hook again, which will cause another save event, and so on. This will cause the PHP process to fail, so you get a 502 from the server.
  
  > This fails with the 502 error. But if I just change the 4th line to `if ($entry->typeId == '19' && !$entry->expiryDate) {` it works ok.
  
  With this adjustment, you've prevented the recursive loop, because you're only calling `Elements::saveElement` once. The second iteration will not cause an additional save, because at that point, the entry has an `expiryDate`.
  
  It's still inefficient because this causes the element to be saved twice instead of once.
  
  > Can anyone help me learn why that would be? I specifically want to update the dates if `eventDate` has changed, so I figured I'd just reapply it everytime. Maybe that's too intensive?
  
  You can figure out what native attributes and custom fields have changed using [`Element::getModifiedAttributes`](https://docs.craftcms.com/api/v3/craft-base-element.html#method-getmodifiedattributes) and [`Element::getModifiedFields`](https://docs.craftcms.com/api/v3/craft-base-element.html#method-getmodifiedfields), but it's much easier and less error-prone to just set the expiry date every time.
  
  The key is to leave out the call to `Craft::$app->elements->saveElement($entry);`. You're already in the `EVENT_BEFORE_SAVE` hook, so the element will be saved after your hook has run. So any changes you make to the element will persist automatically.
  
  > **Comments:**
  > **username_0**: Oh wow, I never even considered it was saving twice...but that makes total sense. Thanks for the detailed explanation!  
  > **username_2**: This bit is most relevant - that's really the issue.  "The key is to leave out the call to Craft::$app->elements->saveElement($entry);. You're already in the EVENT_BEFORE_SAVE hook, so the element will be saved after your hook has run. So any changes you make to the element will persist automatically." I missed it first reading, good work @username_1.  
  
  ---
  
  