Magento 1: Custom Error / Exception Email

Magento has a process that send the website administrator an email when an exception is thrown.  That system works just fine.  When this happens, the rendering of the remainder of the page is halted and the user will be displayed an error page.

Magento Custom Exception Email
Trigger a custom error email in Magento that emulates the exception emails without throwing the exception on the website. This allows for custom error events without disrupting the user experience.

However, what about the instance where you want to receive the same email while not interrupting the user experience.  In other-words, send the email and then continue to render the page page.  There is no default method for this built into Magento.  So continue to read below for a quick fix that allows you to implement an Exception Email without the standard exception process happening.

Note: This code is designed to worith with Magento 1.x versions.

Caution

I’ll get this out of the way from the get-go.  Implementing this could have adverse effects in that your users may not have the experience they/you expect, allowing code to continue may result in excessive server usage, etc.  Use this sparingly and ensure that you are handling errors correctly.

In my case, the situation where I’m using this is to alert me if a CURL request had failed.  The error was being handled correctly already, but aside from reading the logs I have no way of being informed that the CURL request failed.  So that’s where this new email alert comes into play.

The Code

In the code below, replace PromInc with your company name.

Generate and Send the Error

We need to extend the Core helper to add two methods:

  1. Generate a callstack to include in the email
  2. Generate and send the contents of the email

Add the following files.

File:
app/etc/modules/PromInc_Modules.xml

<?xml version="1.0" encoding="utf-8"?>
<config>
 <modules>
  <PromInc_Core>
    <active>true</active>
     <codePool>local</codePool>
  </PromInc_Core>
 </modules>
</config>

File:
app/code/local/PromInc/Core/etc/config.xml

<config>
  <global>
    <helpers>
      <core>
        <rewrite>
          <data>PromInc_Core_Helper_Data</data>
        </rewrite>
      </core>
    </helpers>
  </global>
</config>

File:
app/code/local/PromInc/Core/Helper/Data.php    

<?php
class PromInc_Core_Helper_Data extends Mage_Core_Helper_Data
{

 const LS = "\n";

 /**
 * Get Callstack
 *
 * @param mixed $delim (default self::LS) Line delimiter
 *
 * @return string Callstack
 */
 public function get_callstack($delim=self::LS) {
   $dt = debug_backtrace();
   $cs = '';
   foreach ($dt as $t) {
     $cs .= $t['file'] . ' line ' . $t['line'] . ' calls ' . $t['function'] . "()" . $delim;
   }
   return $cs;
 }


 /**
 * Send an error email to the website adminstrator
 *
 * This is the same error email recieved when an exception is thrown,
 * however this does not interupt the rendering of the rest of the page.
 *
 * This is used for custom functions where you need to be alerted of an instance on the site while not disrupting the user experience.
 *
 * @param mixed $errorTitle (default NULL) Title of the error (default NULL)
 * @param mixed $location (default NULL) Location in code that the error occurred
 * For .php files: __METHOD__
 * For .phtml files: __FILE__
 * @param mixed $extraInfo (default NULL) Optional information to pass in the email
 */
 public function sendExceptionEmail($errorTitle=NULL, $location=NULL, $extraInfo=NULL) {
   $errorDetails = Mage::helper('core')->get_callstack();
   $errorDetails .= self::LS.self::LS;
   $errorDetails .= "Location In Code:".self::LS.$location;
   if( $errorDetails ) {
     $errorDetails .= self::LS.self::LS;
     $errorDetails .= "Error Details:".self::LS.$extraInfo;
    }
    $errorDetails .= self::LS.self::LS;

    $reportData = array(
      0 => $errorTitle,
      1 => $errorDetails,
      "script_name" => __METHOD__,
      "skin" => Mage::app()->getStore()->getCode(),
      "url" => Mage::getSingleton('core/url')->parseUrl( Mage::helper('core/url')->getCurrentUrl() )->getPath()
    );

    if (isset($reportData) && is_array($reportData)) {
      require(Mage::getBaseDir().DS.'errors'.DS.'processor.php');
      $processor = new Error_Processor();
      $processor->saveReport($reportData);
      $processor->sendReport();
    }
 }

}

With these two files added, clear the cache from within the Magento Admin.

  1. System -> Cache Management
  2. Check Configuration and Layouts and click Submit.

Trigger the Exception Email

All that needs to be done now is to trigger the email to send from within your code where an error has occurred.

Mage::helper('core')->sendExceptionEmail("Error Name", "Additional Error Information");

Parameters:

Parameter NameDefault ValueDescription
$errorTitleERROR (Magento)The title/name of the error that has occurred.
$locationNULL

Location in code that the error occurred.

It depends on where you are calling this exception email as to what you want to set this value to:

  • For .php files: __METHOD__
  • For .phtml files: __FILE__
$extraInfoNULL

Extra information that you wish to have passed into the email.

See below for the default contents of the email, which includes a stacktrace.

Note: if you want a new line within this extra content, pass it in with the string “\n” in your variable.

Example of Email Contents

URL: http://www.example.com/var/www/staging/index.php/some/page.html

IP Address: 10.10.10.10

Time: 2015-12-18 22:17:04 GMT

Error:
Error Title Will Go Here

Trace:
/var/www/staging/app/code/core/Mage/Core/Controller/Varien/Action.php line 420 calls newajaxAction() /var/www/staging/app/code/core/Mage/Core/Controller/Varien/Router/Standard.php line 254 calls dispatch() /var/www/staging/app/code/core/Mage/Core/Controller/Varien/Front.php line 176 calls match() /var/www/staging/app/code/core/Mage/Core/Model/App.php line 349 calls dispatch() /var/www/staging/app/Mage.php line 640 calls run() /var/www/staging/index.php line 81 calls run()


Location:
PromInc_Core_Helper_Data::sendExceptionEmail
This is additional information I passed into the error