<p>You can see common patterns for this in Craft's own controllers.</p>

<p>For example in <a href="https://github.com/craftcms/cms/blob/master/src/controllers/EntriesController.php#L499-L507" rel="nofollow noreferrer">https://github.com/craftcms/cms/blob/master/src/controllers/EntriesController.php#L499-L507</a>, if there's a problem, you can catch the error, set it on a route variable and <code>return null</code> so the original template can display it.</p>

<pre><code>Craft::$app-&gt;getSession()-&gt;setError(Craft::t('app', 'Couldn’t duplicate entry.'));

// Send the original entry back to the template, with any validation errors on the clone
$entry-&gt;addErrors($clone-&gt;getErrors());
Craft::$app-&gt;getUrlManager()-&gt;setRouteParams([
    'entry' =&gt; $entry
]);

return null;
</code></pre>

<p>If you don't want to let the original template handle the error, then you should be able to do something like this from your controller:</p>

<pre><code>return $this-&gt;renderTemplate('error', ['error' =&gt; 'Test']);
</code></pre>

CC BY-SA 3.0
2018-04-13T05:07:12.927Z
2018-04-13T05:07:12.927Z
Brad Bell
<p>I'm working on a plugin that hooks into Craft's Guest Entries plugin.</p>

<p>I want to send a confirmation mail after an entry has been saved. This works nicely so far.</p>

<p>Now I want to catch any errors in the mail service. This works nicely so far. Here's my code:</p>

<pre><code>private function mailHandler($from, $to, $subject, $text)
{
    try
    {
        $message = new \craft\mail\Message;

        $message-&gt;setFrom($from);
        $message-&gt;setTo($to);
        $message-&gt;setSubject($subject);
        $message-&gt;setTextBody($text);

        Craft::$app-&gt;mailer-&gt;send($message);
    }
    catch (\Exception $e)
    {
        echo \Craft::$app-&gt;view-&gt;renderTemplate('error', ['error' =&gt; 'Test']);
        die();
    }
}
</code></pre>

<p>There are two problems I'm facing:</p>

<p>1) I have to "stop" the controller action, that's why I need the <code>die</code>. This seems dirty though, is there any other way I could stop the controller?</p>

<p>2) If I do it like this, my error template is rendered, but without any CSS. What am I missing there?</p>

<p>Thanks a ton for your help!</p>

<plugin-development><craft3><controller>
How to render template instead of throwing an error?
# How to render template instead of throwing an error?

(Asked by: username_0 on 2018-04-11)

I'm working on a plugin that hooks into Craft's Guest Entries plugin.
I want to send a confirmation mail after an entry has been saved. This works nicely so far.
Now I want to catch any errors in the mail service. This works nicely so far. Here's my code:
private function mailHandler($from, $to, $subject, $text)
{
    try
    {
        $message = new \craft\mail\Message;

        $message->setFrom($from);
        $message->setTo($to);
        $message->setSubject($subject);
        $message->setTextBody($text);

        Craft::$app->mailer->send($message);
    }
    catch (\Exception $e)
    {
        echo \Craft::$app->view->renderTemplate('error', ['error' => 'Test']);
        die();
    }
}

There are two problems I'm facing:
1) I have to "stop" the controller action, that's why I need the die. This seems dirty though, is there any other way I could stop the controller?
2) If I do it like this, my error template is rendered, but without any CSS. What am I missing there?
Thanks a ton for your help!

**Tags:** plugin-development, craft3, controller

---

## 1 answers

### Answer by username_1 on 2018-04-13. Score: 3

You can see common patterns for this in Craft's own controllers.
For example in https://github.com/craftcms/cms/blob/master/src/controllers/EntriesController.php#L499-L507, if there's a problem, you can catch the error, set it on a route variable and return null so the original template can display it.
Craft::$app->getSession()->setError(Craft::t('app', 'Couldn’t duplicate entry.'));

// Send the original entry back to the template, with any validation errors on the clone
$entry->addErrors($clone->getErrors());
Craft::$app->getUrlManager()->setRouteParams([
    'entry' => $entry
]);

return null;

If you don't want to let the original template handle the error, then you should be able to do something like this from your controller:
return $this->renderTemplate('error', ['error' => 'Test']);


---

