ice framework documentation ice doc v1.10.1
Class Ice

Exception

    
namespace Ice;

/**
 * Exception class.
 *
 * @package     Ice/Exception
 * @category    Error
 * @author      Ice Team
 * @copyright   (c) 2014-2023 Ice Team
 * @license     http://iceframework.org/license
 */
class Exception extends \Exception
{
    /**
     * Creates a new exception.
     * Translate exception's message using the [I18n] class.
     *
     * @param mixed message Error message
     * @param mixed code The exception code
     * @param Exception|Throwable previous Previous exception
     */
    public function __construct(var message = "", code = 0, previous = null)
    {
        var di, values, str;

        let di = Di::$fetch();

        if typeof message == "array" {
            let values = array_slice(message, 1),
                str = message[0];
        } else {
            let values = null,
                str = message;
        }

        // Check if translation module is available.
        if di->has("i18n") {
            let message = di->get("i18n")->translate(str, values);
        } elseif typeof values == "array" {
            // Check if values is associative or sequential
            if count(array_filter(array_keys(values), "is_string")) {
                let message = strtr(str, values);
            } else {
                let message = call_user_func_array("sprintf", message);
            }
        }

        parent::__construct((string) message, (int) code, previous);
    }

    /**
     * Get the full trace as string.
     *
     * @param Exception|Throwable $e
     * @return string
     */
    public function getFullTraceAsString(e)
    {
        var output, frame, args, arg, node;
        int count = 0;

        let output = "";

        for frame in e->getTrace() {
            let args = "";

            if isset frame["args"] {
                let node = [];

                for arg in frame["args"] {
                    switch typeof arg {
                        case "string":
                            let node[] = "'" . arg . "'";
                        break;
                        case "array":
                            let node[] = "Array";
                        break;
                        case "NULL":
                            let node[] = "NULL";
                        break;
                        case "boolean":
                            let node[] = arg ? "true" : "false";
                        break;
                        case "object":
                            let node[] = "Object(" . get_class(arg) . ")";
                        break;
                        case "resource":
                            let node[] = arg;
                        break;
                        default:
                            let node[] = arg;
                        break;
                    }
                }
                let args = join(", ", node);
            }

            let output .= sprintf(
                    "#%s %s: %s(%s)\n",
                    count,
                    (isset frame["file"] ? frame["file"] . "(" . frame["line"] . ")" : "[internal function]"),
                    (isset frame["class"] ? frame["class"] . frame["type"] . frame["function"] : frame["function"]),
                    args
                ),
                count++;
        }
        return output;
    }

    /**
     * PHP error handler, converts all errors into ErrorExceptions. This handler respects error_reporting settings.
     *
     * @throws ErrorException
     * @return true
     */
    public static function errorHandler(int code, string message, string file = null, int line = 0, array context = [])
    {
        if error_reporting() & code {
            // This error is not suppressed by current error reporting settings
            // Convert the error into an ErrorException
            throw new \ErrorException(message, code, 0, file, line);
        }
        // Do not execute the PHP error handler
        return true;
    }

    /**
     * Inline exception handler, displays the error message, source of the exception, and the stack trace of the error.
     *
     * @param Exception|Throwable $e
     * @return void
     */
    public static function handler(e)
    {
        var di, response;

        let di = Di::$fetch(),
            response = di->get("response");

        // Clear the previous response body
        response->setBody("");

        di->applyHook("exception.after.uncaught", [e, di]);

        if response->getBody() {
            echo response->send();
        } else {
            throw e;
        }

        exit(1);
    }

    /**
     * Catches errors that are not caught by the error handler.
     * E_PARSE, E_ERROR, E_CORE_ERROR, E_USER_ERROR
     *
     * @return  void
     */
    public static function shutdownHandler()
    {
        var e;

        let e = error_get_last();
        if typeof e == "array" && in_array(e["type"], [E_PARSE, E_ERROR, E_CORE_ERROR, E_USER_ERROR]) {
            // Clean the output buffer
            ob_get_level();
            ob_clean();
            // Fake an exception for nice debugging
            Exception::handler(new \ErrorException(e["message"], e["type"], 0, e["file"], e["line"]));
            // Shutdown now to avoid a "death loop"
            exit(1);
        }
    }
}