<?php
namespace Lia;
/**
* Catches exceptions & provides helpful error messages
*/
class ExceptionCatcher {
protected $trace;
protected $message;
protected $dir;
protected $subs = [];
public $liaMessage;
/**
* prints the informative message (use output buffering if you want)
* @param Exception $e
*/
static public function message($e){
// echo 'zippity zeep';
// exit;
echo "\n";
$trace = $e->getTrace();
foreach ($trace as $index=>$row){
$row['class'] = $row['class'] ?? 'n/a';
if ($row['class']=='Lia\\Addon\\Resources'
&&$row['function']=='addFile'
){
$msg = $e->getMessage();
echo 'Message: '.$msg;
static::report($trace[$index]??null);
break;
}
if ($row['class']=='Lia\\Addon\\Cache'
&&$row['function']=='get_cache_file_content'
){
$msg = $e->getMessage();
$begin = 'file_get_contents(): Filename cannot be empty';
if ($msg == $begin) {
echo 'Message: You probably need to set the cache dir.';
} else {
echo "Message: There was an error with cache, but i don't know what it is.";
}
static::report($trace[$index]??null);
break;
}
if ($row['class']=='Lia\\Addon\\View'
&&$row['function']=='view'
){
$msg = $e->getMessage();
$begin = 'Undefined index: ';
if (substr($msg,0,strlen($begin))==$begin){
$name = substr($msg,strlen($begin));
echo "Message: View was not found. Either the namespace is unavailable or the view was not set. The key is `{$name}`";
} else {
echo "Message: There was an error with views, but i don't know what it is.";
}
$dir = dirname(__DIR__);
$len = strlen($dir);
$report_row = $trace[$index];
while (substr($report_row['file'], 0, $len)==$dir){
$report_row = $trace[++$index];
}
static::report($trace[$index]??null);
break;
}
if ($row['class']=='Lia\\Addon\\Hook'
&&$row['function']=='call'
){
$msg = $e->getMessage();
$begin = 'Undefined index: ';
if (substr($msg,0,strlen($begin))==$begin){
echo "Message: Hook named `".substr($msg,strlen($begin)).'` does not exist and cannot be called';
} else {
// echo "Message: You tried to call an api method that is not set.";
echo "I don't know what the problem is, but I think it starts at this:";
}
static::report($trace[$index]??null);
break;
}
/**
* report an error on a magic __call() on Lia
*/
if ($row['class']=='Lia'
&&$row['function']=='__call'
){
$msg = $e->getMessage();
$begin = 'Undefined index: ';
if (substr($msg,0,strlen($begin))==$begin){
echo "Message: Api method `".substr($msg,strlen($begin)).'` does note exist on Lia';
} else {
// echo "Message: You tried to call an api method that is not set.";
echo "I don't know what the problem is, but I think it starts at this:";
}
static::report($trace[$index]??null);
break;
}
}
}
/**
* prints the stack trace
* @param Exception $e
*/
static public function trace($e){
throw $e;
// $trace = $e->getTrace();
//
// echo "\n\n---begin stacktrace---\n";
//
// print_r($trace);
}
/**
* throw the given error after printing a custom trace and message
*
* @param Exception $e
* @param $print_messages false to disable printing of the custom trace & message output
*/
static public function throw($e, $print_messages=true){
if ($print_messages){
static::trace($e);
static::message($e);
}
throw $e;
}
static public function report($trace_entry){
echo "\n\n";
echo "Called from: "
."\n - File: ".$trace_entry['file']
."\n - Line: ".$trace_entry['line']
."\n - Function: ".$trace_entry['function']
;
echo "\n\n";
}
static public function dir(){
return '--dir-not-implemented-yet--';
}
static public function getExternalTrace($exception){
// if ($this->trace!=null)return $this->trace;
$list = $exception->getTrace();
$et = null;
$message = "";
$dir = static::dir($exception);
foreach ($list as $depth => $trace){ #2 [internal function]: Lia\Route\Router->global_contentFor()
$trace['line'] = $trace['line'] ?? '--n/a--';
$file = $trace['file'] ?? '--n/a--';
$trace['file'] = $file;
$sub = substr($file,0,strlen($dir));
if ($file=='--n/a--'){
$message .= "Anonymous functions at stack #".$depth."\n";
continue;
} else if ($sub==$dir){
continue;
}
$et = $trace;
$next = $list[$depth+1] ?? null;
break;
}
$trace = (object) array_merge(
['raw'=>$et,
'depth'=>$depth,
'extraInfo'=>$message,
],
$et,
);
$trace->calledClass = $trace->class;
unset($trace->class);
$trace->calledFunction = $trace->function;
if ($trace->function=='__call'){
//@TODO get the args (using debug_backtrace in the constructor) & provide the actual method call.
}
unset($trace->function);
$trace->fromClass = $next['class'] ?? '--n/a--';
$trace->fromFunction = $next['function'] ?? '--n/a--';
$trace->message = $exception->getMessage();
return $trace;
}
}