Version 2.0.0
This commit is contained in:
parent
40e172d5d1
commit
7a70b70931
10 changed files with 206 additions and 154 deletions
10
changelog.md
10
changelog.md
|
|
@ -2,6 +2,16 @@
|
||||||
|
|
||||||
All notable changes to `ExceptionHandler` will be documented in this file.
|
All notable changes to `ExceptionHandler` will be documented in this file.
|
||||||
|
|
||||||
|
# version 2.0.0
|
||||||
|
- Changed enhance getAnonymizedMessage (for DB queries)
|
||||||
|
- Changed Support only for laravel 10
|
||||||
|
- Added env element EXCEPTION_MAIL_LIST
|
||||||
|
|
||||||
|
# version 0.1.1
|
||||||
|
- Changed better parsing for email recipients
|
||||||
|
- Changed if no recipients are available, a warning will be emitted, also native Laravel report method will be called instead.
|
||||||
|
- Changed if mail report fails, native reporting method will be called.
|
||||||
|
|
||||||
# version 0.1.0
|
# version 0.1.0
|
||||||
- Add a a method to manually send exception by email (plus the same to call statically).
|
- Add a a method to manually send exception by email (plus the same to call statically).
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,13 +17,11 @@
|
||||||
"Policies"
|
"Policies"
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"illuminate/support": "~7|~8|~9",
|
"illuminate/support": "~10",
|
||||||
"laravel/framework": "~7|~8|~9"
|
"laravel/framework": "~10"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "~9.0",
|
"slevomat/coding-standard": "^8.10"
|
||||||
"squizlabs/php_codesniffer": "^3.5",
|
|
||||||
"orchestra/testbench": "^6.13"
|
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
|
|
@ -41,5 +39,10 @@
|
||||||
"Kwaadpepper\\ExceptionHandler\\ExceptionHandlerServiceProvider"
|
"Kwaadpepper\\ExceptionHandler\\ExceptionHandlerServiceProvider"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"allow-plugins": {
|
||||||
|
"dealerdirect/phpcodesniffer-composer-installer": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,5 +11,5 @@ return [
|
||||||
* Put a developper secured mailbox in here
|
* Put a developper secured mailbox in here
|
||||||
* so you can receive email if things go mad
|
* so you can receive email if things go mad
|
||||||
*/
|
*/
|
||||||
'contactsList' => []
|
'contactsList' => collect(explode(',', env('EXCEPTION_MAIL_LIST')))->all(),
|
||||||
];
|
];
|
||||||
|
|
|
||||||
171
phpcs.xml
171
phpcs.xml
|
|
@ -1,74 +1,86 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<ruleset name="RealWorld" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="vendor/squizlabs/php_codesniffer/phpcs.xsd">
|
<ruleset name="LDC Laravel"
|
||||||
<arg name="colors"/>
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="vendor/squizlabs/php_codesniffer/phpcs.xsd">
|
||||||
<arg name="extensions" value="php"/>
|
<description>Created with the PHP Coding Standard Generator. http://edorian.github.com/php-coding-standard-generator/</description>
|
||||||
|
<arg name="colors" />
|
||||||
|
<arg name="extensions" value="php" />
|
||||||
<file>src/</file>
|
<file>src/</file>
|
||||||
<file>tests/</file>
|
<rule ref="PSR1" />
|
||||||
<description>Created with the PHP Coding Standard Generator. http://edorian.github.com/php-coding-standard-generator/
|
<rule ref="PSR12" />
|
||||||
</description>
|
|
||||||
<rule ref="Generic.CodeAnalysis.EmptyStatement" />
|
<rule ref="Generic.Classes.DuplicateClassName"/>
|
||||||
<rule ref="Generic.CodeAnalysis.ForLoopShouldBeWhileLoop" />
|
<rule ref="Generic.CodeAnalysis.EmptyStatement"/>
|
||||||
<rule ref="Generic.CodeAnalysis.ForLoopWithTestFunctionCall" />
|
<rule ref="Generic.CodeAnalysis.ForLoopShouldBeWhileLoop"/>
|
||||||
<rule ref="Generic.CodeAnalysis.JumbledIncrementer" />
|
<rule ref="Generic.CodeAnalysis.ForLoopWithTestFunctionCall"/>
|
||||||
<rule ref="Generic.CodeAnalysis.UnconditionalIfStatement" />
|
<rule ref="Generic.CodeAnalysis.JumbledIncrementer"/>
|
||||||
<rule ref="Generic.CodeAnalysis.UnnecessaryFinalModifier" />
|
<rule ref="Generic.CodeAnalysis.UnconditionalIfStatement"/>
|
||||||
<rule ref="Generic.CodeAnalysis.UnusedFunctionParameter" />
|
<rule ref="Generic.CodeAnalysis.UnnecessaryFinalModifier"/>
|
||||||
<rule ref="Generic.CodeAnalysis.UselessOverridingMethod" />
|
<rule ref="Generic.CodeAnalysis.UnusedFunctionParameter"/>
|
||||||
<rule ref="Generic.Commenting.Todo" />
|
<rule ref="Generic.CodeAnalysis.UselessOverridingMethod"/>
|
||||||
<rule ref="Generic.Commenting.Fixme" />
|
<rule ref="Generic.Commenting.DocComment.SpacingBeforeTags"/>
|
||||||
<rule ref="Generic.ControlStructures.InlineControlStructure" />
|
<rule ref="Generic.Commenting.Todo"/>
|
||||||
<rule ref="Generic.Files.ByteOrderMark" />
|
<rule ref="Generic.Commenting.Fixme"/>
|
||||||
<rule ref="Generic.Files.LineEndings" />
|
<rule ref="Generic.ControlStructures.InlineControlStructure"/>
|
||||||
<rule ref="Generic.Files.LineLength">
|
<rule ref="Generic.Files.ByteOrderMark"/>
|
||||||
<properties>
|
<rule ref="Generic.Files.LineEndings"/>
|
||||||
<property name="lineLimit" value="120"/>
|
<rule ref="Generic.Files.LineLength"/>
|
||||||
<property name="absoluteLineLimit" value="0"/>
|
<rule ref="Generic.Formatting.DisallowMultipleStatements"/>
|
||||||
</properties>
|
<rule ref="Generic.Formatting.MultipleStatementAlignment"/>
|
||||||
|
<rule ref="Generic.Formatting.NoSpaceAfterCast"/>
|
||||||
|
<rule ref="Generic.Functions.CallTimePassByReference"/>
|
||||||
|
<rule ref="Generic.Functions.FunctionCallArgumentSpacing"/>
|
||||||
|
<rule ref="Generic.Metrics.CyclomaticComplexity"/>
|
||||||
|
<rule ref="Generic.Metrics.NestingLevel"/>
|
||||||
|
<rule ref="Generic.NamingConventions.ConstructorName"/>
|
||||||
|
<rule ref="Generic.NamingConventions.UpperCaseConstantName"/>
|
||||||
|
<rule ref="Generic.NamingConventions.CamelCapsFunctionName"/>
|
||||||
|
<rule ref="Generic.PHP.DeprecatedFunctions"/>
|
||||||
|
<rule ref="Generic.PHP.DisallowShortOpenTag"/>
|
||||||
|
<rule ref="Generic.PHP.ForbiddenFunctions"/>
|
||||||
|
<rule ref="Generic.PHP.NoSilencedErrors"/>
|
||||||
|
<rule ref="Generic.Strings.UnnecessaryStringConcat"/>
|
||||||
|
<rule ref="Generic.WhiteSpace.DisallowTabIndent"/>
|
||||||
|
<rule ref="Generic.WhiteSpace.ScopeIndent"/>
|
||||||
|
<rule ref="MySource.PHP.EvalObjectFactory"/>
|
||||||
|
<rule ref="MySource.PHP.GetRequestData"/>
|
||||||
|
<rule ref="MySource.PHP.AjaxNullComparison"/>
|
||||||
|
<rule ref="PEAR.Classes.ClassDeclaration"/>
|
||||||
|
<rule ref="PEAR.Commenting.InlineComment"/>
|
||||||
|
<rule ref="PSR1.Classes.ClassDeclaration"/>
|
||||||
|
<rule ref="PSR1.Files.SideEffects"/>
|
||||||
|
<rule ref="PSR2.Classes.ClassDeclaration"/>
|
||||||
|
<rule ref="PSR2.Classes.PropertyDeclaration"/>
|
||||||
|
<rule ref="PSR2.ControlStructures.ElseIfDeclaration"/>
|
||||||
|
<rule ref="PSR2.ControlStructures.SwitchDeclaration"/>
|
||||||
|
<rule ref="PSR2.Files.EndFileNewline"/>
|
||||||
|
<rule ref="PSR2.Methods.MethodDeclaration"/>
|
||||||
|
<rule ref="PSR2.Namespaces.NamespaceDeclaration"/>
|
||||||
|
<rule ref="PSR2.Namespaces.UseDeclaration"/>
|
||||||
|
<rule ref="Squiz.PHP.CommentedOutCode"/>
|
||||||
|
<rule ref="Squiz.PHP.DisallowMultipleAssignments">
|
||||||
|
<exclude name="Squiz.PHP.DisallowMultipleAssignments.FoundInControlStructure" />
|
||||||
</rule>
|
</rule>
|
||||||
<rule ref="Generic.Formatting.DisallowMultipleStatements" />
|
<rule ref="Squiz.PHP.DisallowSizeFunctionsInLoops"/>
|
||||||
<rule ref="Generic.Formatting.NoSpaceAfterCast" />
|
|
||||||
<rule ref="Generic.Functions.CallTimePassByReference" />
|
|
||||||
<rule ref="Generic.Functions.FunctionCallArgumentSpacing" />
|
|
||||||
<rule ref="Generic.Metrics.CyclomaticComplexity" />
|
|
||||||
<rule ref="Generic.Metrics.NestingLevel" />
|
|
||||||
<rule ref="Generic.NamingConventions.ConstructorName" />
|
|
||||||
<rule ref="Generic.NamingConventions.UpperCaseConstantName" />
|
|
||||||
<rule ref="Generic.NamingConventions.CamelCapsFunctionName" />
|
|
||||||
<rule ref="Generic.PHP.DeprecatedFunctions" />
|
|
||||||
<rule ref="Generic.PHP.DisallowShortOpenTag" />
|
|
||||||
<rule ref="Generic.PHP.ForbiddenFunctions" />
|
|
||||||
<rule ref="Generic.PHP.LowerCaseConstant" />
|
|
||||||
<rule ref="Generic.PHP.NoSilencedErrors" />
|
|
||||||
<rule ref="Generic.Strings.UnnecessaryStringConcat" />
|
|
||||||
<rule ref="Generic.WhiteSpace.DisallowTabIndent" />
|
|
||||||
<rule ref="Generic.WhiteSpace.ScopeIndent" />
|
|
||||||
<rule ref="MySource.PHP.EvalObjectFactory" />
|
|
||||||
<rule ref="MySource.PHP.GetRequestData" />
|
|
||||||
<rule ref="MySource.PHP.AjaxNullComparison" />
|
|
||||||
<rule ref="PEAR.Classes.ClassDeclaration" />
|
|
||||||
<rule ref="PEAR.Commenting.InlineComment" />
|
|
||||||
<rule ref="PSR1.Classes.ClassDeclaration" />
|
|
||||||
<rule ref="PSR1.Files.SideEffects" />
|
|
||||||
<rule ref="Squiz.PHP.CommentedOutCode" />
|
|
||||||
<rule ref="Squiz.PHP.DisallowSizeFunctionsInLoops" />
|
|
||||||
<rule ref="Squiz.PHP.DiscouragedFunctions">
|
<rule ref="Squiz.PHP.DiscouragedFunctions">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="error" value="true" />
|
<property name="error" value="true"/>
|
||||||
</properties>
|
</properties>
|
||||||
</rule>
|
</rule>
|
||||||
<rule ref="Squiz.PHP.Eval" />
|
<rule ref="Squiz.PHP.Eval"/>
|
||||||
<rule ref="Squiz.PHP.GlobalKeyword" />
|
<rule ref="Squiz.PHP.GlobalKeyword"/>
|
||||||
<rule ref="Squiz.PHP.Heredoc" />
|
<rule ref="Squiz.PHP.Heredoc"/>
|
||||||
<rule ref="Squiz.PHP.InnerFunctions" />
|
<rule ref="Squiz.PHP.InnerFunctions"/>
|
||||||
<rule ref="Squiz.PHP.LowercasePHPFunctions" />
|
<rule ref="Squiz.PHP.LowercasePHPFunctions"/>
|
||||||
<rule ref="Squiz.PHP.NonExecutableCode" />
|
<rule ref="Squiz.PHP.NonExecutableCode"/>
|
||||||
<rule ref="Squiz.Scope.MemberVarScope" />
|
<rule ref="Squiz.Scope.MemberVarScope"/>
|
||||||
<rule ref="Squiz.Scope.MethodScope" />
|
<rule ref="Squiz.Scope.MethodScope"/>
|
||||||
<rule ref="Squiz.Scope.StaticThisUsage" />
|
<rule ref="Squiz.Scope.StaticThisUsage"/>
|
||||||
<rule ref="Squiz.WhiteSpace.MemberVarSpacing" />
|
<rule ref="Squiz.WhiteSpace.LanguageConstructSpacing"/>
|
||||||
<rule ref="Squiz.WhiteSpace.ObjectOperatorSpacing">
|
<rule ref="Squiz.WhiteSpace.LogicalOperatorSpacing"/>
|
||||||
|
<rule ref="Squiz.WhiteSpace.MemberVarSpacing">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="ignoreNewlines" value="true"/>
|
<property name="spacingBeforeFirst " value="false"/>
|
||||||
</properties>
|
</properties>
|
||||||
</rule>
|
</rule>
|
||||||
<rule ref="Squiz.WhiteSpace.OperatorSpacing">
|
<rule ref="Squiz.WhiteSpace.OperatorSpacing">
|
||||||
|
|
@ -76,12 +88,39 @@
|
||||||
<property name="ignoreNewlines" value="true"/>
|
<property name="ignoreNewlines" value="true"/>
|
||||||
</properties>
|
</properties>
|
||||||
</rule>
|
</rule>
|
||||||
<rule ref="Squiz.WhiteSpace.ScopeKeywordSpacing" />
|
<rule ref="Squiz.WhiteSpace.ObjectOperatorSpacing">
|
||||||
<rule ref="Squiz.WhiteSpace.SemicolonSpacing" />
|
<properties>
|
||||||
|
<property name="ignoreNewlines" value="true"/>
|
||||||
|
</properties>
|
||||||
|
</rule>
|
||||||
|
<rule ref="Squiz.WhiteSpace.ScopeKeywordSpacing"/>
|
||||||
|
<rule ref="Squiz.WhiteSpace.SemicolonSpacing"/>
|
||||||
|
<rule ref="Squiz.Commenting.BlockComment">
|
||||||
|
<exclude name="Squiz.Commenting.BlockComment.WrongStart" />
|
||||||
|
</rule>
|
||||||
|
<rule ref="Squiz.Commenting.ClassComment">
|
||||||
|
<exclude name="Squiz.Commenting.ClassComment.Missing" />
|
||||||
|
<exclude name="Squiz.Commenting.ClassComment.TagNotAllowed" />
|
||||||
|
</rule>
|
||||||
|
<rule ref="Squiz.Commenting.DocCommentAlignment"/>
|
||||||
|
<rule ref="Squiz.Commenting.EmptyCatchComment"/>
|
||||||
|
<rule ref="Squiz.Commenting.FunctionComment">
|
||||||
|
<exclude name="Squiz.Commenting.FunctionComment.MissingParamComment" />
|
||||||
|
</rule>
|
||||||
|
<rule ref="Squiz.Commenting.FunctionCommentThrowTag"/>
|
||||||
|
<rule ref="Squiz.Commenting.InlineComment">
|
||||||
|
<exclude name="Squiz.Commenting.InlineComment.DocBlock" />
|
||||||
|
</rule>
|
||||||
|
<rule ref="Squiz.Commenting.LongConditionClosingComment">
|
||||||
|
<exclude name="Squiz.Commenting.LongConditionClosingComment.SpacingBefore" />
|
||||||
|
</rule>
|
||||||
|
<rule ref="Squiz.Commenting.PostStatementComment"/>
|
||||||
|
<rule ref="Squiz.Commenting.VariableComment"/>
|
||||||
|
<rule ref="SlevomatCodingStandard.Namespaces.UnusedUses.UnusedUse" />
|
||||||
|
|
||||||
<!-- For Laravel migrations -->
|
<!-- For Laravel migrations -->
|
||||||
<rule ref="PSR1.Classes.ClassDeclaration.MissingNamespace">
|
<rule ref="PSR1.Classes.ClassDeclaration.MissingNamespace">
|
||||||
<exclude-pattern>*/database/migrations/*</exclude-pattern>
|
<exclude-pattern>*/database/migrations/*</exclude-pattern>
|
||||||
</rule>
|
</rule>
|
||||||
|
|
||||||
</ruleset>
|
</ruleset>
|
||||||
|
|
|
||||||
|
|
@ -17,15 +17,18 @@ $ composer require kwaadpepper/exception-handler
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
- `php artisan handler:install`
|
- `php artisan handler:install`
|
||||||
- `php artisan vendor:publish --provider "Kwaadpepper\\ExceptionHandler\\ExceptionHandlerServiceProvider" --tag config`
|
- Change configuration in `config/exception-handler.php` if needed.
|
||||||
- Change configuration in `config/exception-handler.php`
|
- Put at least your team email in the above file in `contactsList` array or using `.env` put a list in `EXCEPTION_MAIL_LIST`. You can add emails separated with `,` like `admin1@email.com,admin2@email.com`
|
||||||
- put at least your team email in the above file in `contactsList` array
|
|
||||||
|
|
||||||
You can uninstall it by using `php artisan handler:remove` or just revert changes in Exception/Handler.php
|
You can uninstall it by using `php artisan handler:remove` or just revert changes in Exception/Handler.php
|
||||||
## Change log
|
## Change log
|
||||||
|
|
||||||
Please see the [changelog](changelog.md) for more information on what has changed recently.
|
Please see the [changelog](changelog.md) for more information on what has changed recently.
|
||||||
|
|
||||||
|
# Todo
|
||||||
|
|
||||||
|
- Add other transmission possibilities (other than mail)
|
||||||
|
|
||||||
## Security
|
## Security
|
||||||
|
|
||||||
If you discover any security related issues, please email `github@jeremydev.ovh` instead of using the issue tracker.
|
If you discover any security related issues, please email `github@jeremydev.ovh` instead of using the issue tracker.
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ use Illuminate\Support\Facades\File;
|
||||||
|
|
||||||
class InstallHandler extends Command
|
class InstallHandler extends Command
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name and signature of the console command.
|
* The name and signature of the console command.
|
||||||
*
|
*
|
||||||
|
|
@ -35,8 +34,8 @@ class InstallHandler extends Command
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
$handlerFile = File::get($handlerPath);
|
$handlerFile = File::get($handlerPath);
|
||||||
$find = 'use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;';
|
$find = 'use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;';
|
||||||
$replace = 'use Kwaadpepper\ExceptionHandler\Exceptions\ExceptionHandler;';
|
$replace = 'use Kwaadpepper\ExceptionHandler\Exceptions\ExceptionHandler;';
|
||||||
if (\strpos($handlerFile, $replace) !== false) {
|
if (\strpos($handlerFile, $replace) !== false) {
|
||||||
$this->error('Exception handler seems to already be installed');
|
$this->error('Exception handler seems to already be installed');
|
||||||
exit;
|
exit;
|
||||||
|
|
@ -49,8 +48,8 @@ class InstallHandler extends Command
|
||||||
File::put($handlerPath, $handlerFile);
|
File::put($handlerPath, $handlerFile);
|
||||||
$this->info("Replaced $handlerPath");
|
$this->info("Replaced $handlerPath");
|
||||||
|
|
||||||
$source = __DIR__ . '/../../../config/exception-handler.php';
|
$source = __DIR__ . '/../../../config/exception-handler.php';
|
||||||
$dest = \config_path('exception-handler.php');
|
$dest = \config_path('exception-handler.php');
|
||||||
$destExist = File::exists($dest);
|
$destExist = File::exists($dest);
|
||||||
if (
|
if (
|
||||||
!$destExist or
|
!$destExist or
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ use Illuminate\Support\Facades\File;
|
||||||
|
|
||||||
class RemoveHandler extends Command
|
class RemoveHandler extends Command
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name and signature of the console command.
|
* The name and signature of the console command.
|
||||||
*
|
*
|
||||||
|
|
@ -35,8 +34,8 @@ class RemoveHandler extends Command
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
$handlerFile = File::get($handlerPath);
|
$handlerFile = File::get($handlerPath);
|
||||||
$find = 'use Kwaadpepper\ExceptionHandler\Exceptions\ExceptionHandler;';
|
$find = 'use Kwaadpepper\ExceptionHandler\Exceptions\ExceptionHandler;';
|
||||||
$replace = 'use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;';
|
$replace = 'use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;';
|
||||||
if (\strpos($handlerFile, $replace) !== false) {
|
if (\strpos($handlerFile, $replace) !== false) {
|
||||||
$this->error('Exception handler seems to already be removed');
|
$this->error('Exception handler seems to already be removed');
|
||||||
exit;
|
exit;
|
||||||
|
|
@ -48,7 +47,7 @@ class RemoveHandler extends Command
|
||||||
$handlerFile = \str_replace($find, $replace, $handlerFile);
|
$handlerFile = \str_replace($find, $replace, $handlerFile);
|
||||||
File::put($handlerPath, $handlerFile);
|
File::put($handlerPath, $handlerFile);
|
||||||
|
|
||||||
$source = \config_path('exception-handler.php');
|
$source = \config_path('exception-handler.php');
|
||||||
$sourceExist = File::exists($source);
|
$sourceExist = File::exists($source);
|
||||||
if (
|
if (
|
||||||
$sourceExist and
|
$sourceExist and
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ use Illuminate\Support\ServiceProvider;
|
||||||
|
|
||||||
class ExceptionHandlerServiceProvider extends ServiceProvider
|
class ExceptionHandlerServiceProvider extends ServiceProvider
|
||||||
{
|
{
|
||||||
|
|
||||||
protected $commands = [
|
protected $commands = [
|
||||||
'Kwaadpepper\ExceptionHandler\Console\Commands\InstallHandler',
|
'Kwaadpepper\ExceptionHandler\Console\Commands\InstallHandler',
|
||||||
'Kwaadpepper\ExceptionHandler\Console\Commands\RemoveHandler'
|
'Kwaadpepper\ExceptionHandler\Console\Commands\RemoveHandler'
|
||||||
|
|
|
||||||
|
|
@ -9,44 +9,29 @@ use Illuminate\Support\Facades\Mail;
|
||||||
|
|
||||||
class ExceptionHandler extends Handler
|
class ExceptionHandler extends Handler
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new exception handler instance.
|
* Create a new exception handler instance.
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Contracts\Container\Container $container
|
* @param \Illuminate\Contracts\Container\Container $container
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function __construct(Container $container)
|
public function __construct(Container $container)
|
||||||
{
|
{
|
||||||
parent::__construct($container);
|
parent::__construct($container);
|
||||||
if (
|
$this->reportable($this->reportExceptionByEmail());
|
||||||
\strpos(app()->version(), '8') === 0 or
|
|
||||||
\strpos(app()->version(), '9') === 0
|
|
||||||
) {
|
|
||||||
$this->reportable($this->reportExceptionByEmail());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Report or log an exception.
|
* Report or log an exception.
|
||||||
*
|
*
|
||||||
* @param \Throwable $exception
|
* @param \Throwable $e
|
||||||
* @return void
|
* @return void
|
||||||
*
|
|
||||||
* @throws \Exception
|
|
||||||
*/
|
*/
|
||||||
public function report(\Throwable $e)
|
public function report(\Throwable $e)
|
||||||
{
|
{
|
||||||
if (get_class($e) == RedirectTo::class) {
|
if (get_class($e) == RedirectTo::class) {
|
||||||
abort(redirect($e->url));
|
abort(redirect($e->url));
|
||||||
}
|
}
|
||||||
// ? If in laravel 7 and and error occurs when sending mail.
|
|
||||||
if (
|
|
||||||
\strpos(app()->version(), '7') === 0 and
|
|
||||||
!$this->reportExceptionByEmail()($e)
|
|
||||||
) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
parent::report($e);
|
parent::report($e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -80,47 +65,52 @@ class ExceptionHandler extends Handler
|
||||||
private function reportExceptionByEmail(): \Closure
|
private function reportExceptionByEmail(): \Closure
|
||||||
{
|
{
|
||||||
return function (\Throwable $e) {
|
return function (\Throwable $e) {
|
||||||
$dest = config('exception-handler.contactsList', config('mail.from.address'));
|
if ($this->shouldntReport($e)) {
|
||||||
try {
|
return false;
|
||||||
if ($dest and config('exception-handler.enableMaiLog')) {
|
|
||||||
if ($this->shouldntReport($e)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
Mail::send([
|
|
||||||
'html' => 'exception-handler::emails.exception',
|
|
||||||
'text' => 'exception-handler::emails.exception-plain'
|
|
||||||
], [
|
|
||||||
'appName' => config('app.name'),
|
|
||||||
'code' => $e->getCode(),
|
|
||||||
'line' => $e->getLine(),
|
|
||||||
'ename' => \get_class($e),
|
|
||||||
'emessage' => $this->getAnonymizedMessage($e->getMessage()),
|
|
||||||
'file' => str_replace(\realpath(\sprintf('%s/../', \app_path())), '', $e->getFile()),
|
|
||||||
'stackTrace' => $this->getAnonymizedStackTrace($e),
|
|
||||||
'uri' => app()->runningInConsole() ?
|
|
||||||
'CONSOLE' : (
|
|
||||||
(request() and request()->fullUrl()) ?
|
|
||||||
request()->fullUrl() : 'none')
|
|
||||||
], function ($m) use ($dest) {
|
|
||||||
// ? Is laravel 9 (https://laravel.com/docs/master/upgrade#symfony-mailer)
|
|
||||||
if(\strpos(app()->version(), '9') !== 0) {
|
|
||||||
/** @var \Illuminate\Mail\Message $m */
|
|
||||||
$m->setTo(
|
|
||||||
$dest,
|
|
||||||
sprintf('%s Exception Handler', config('app.name'))
|
|
||||||
)->setSubject('Need help !, an error occured in your application, please check Logs ASAP');
|
|
||||||
} else {
|
|
||||||
/** @var \Illuminate\Mail\Message $m */
|
|
||||||
$m->to(
|
|
||||||
$dest,
|
|
||||||
sprintf('%s Exception Handler', config('app.name'))
|
|
||||||
)->subject('Need help !, an error occured in your application, please check Logs ASAP');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} catch (\Error $e) {
|
|
||||||
Log::critical('Handler could not send Exception email', ['exception' => $e]);
|
|
||||||
}
|
}
|
||||||
|
// * Ignore NoContactException.
|
||||||
|
if ($e instanceof NoContactException) {
|
||||||
|
Log::critical($e->getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$dest = \collect(config('exception-handler.contactsList', config('mail.from.address')))->filter();
|
||||||
|
try {
|
||||||
|
if (!config('exception-handler.enableMaiLog')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!$dest->count()) {
|
||||||
|
throw new NoContactException(
|
||||||
|
'No contact in `EXCEPTION_MAIL_LIST` nor `exception-handler.contactsList` config',
|
||||||
|
0,
|
||||||
|
$e
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Mail::send([
|
||||||
|
'html' => 'exception-handler::emails.exception',
|
||||||
|
'text' => 'exception-handler::emails.exception-plain'
|
||||||
|
], [
|
||||||
|
'appName' => config('app.name'),
|
||||||
|
'code' => $e->getCode(),
|
||||||
|
'line' => $e->getLine(),
|
||||||
|
'ename' => \get_class($e),
|
||||||
|
'emessage' => self::getAnonymizedMessage($e->getMessage()),
|
||||||
|
'file' => str_replace(\realpath(\sprintf('%s/../', \app_path())), '', $e->getFile()),
|
||||||
|
'stackTrace' => self::getAnonymizedStackTrace($e),
|
||||||
|
'uri' => app()->runningInConsole() ?
|
||||||
|
'CONSOLE' : (
|
||||||
|
(request() and request()->fullUrl()) ?
|
||||||
|
request()->fullUrl() : 'none')
|
||||||
|
], function ($m) use ($dest) {
|
||||||
|
/** @var \Illuminate\Mail\Message $m */
|
||||||
|
$m->to(
|
||||||
|
$dest->all(),
|
||||||
|
sprintf('%s Exception Handler', config('app.name'))
|
||||||
|
)->subject('Need help !, an error occured in your application, please check Logs ASAP');
|
||||||
|
});
|
||||||
|
} catch (\Error $reportE) {
|
||||||
|
parent::report($e);
|
||||||
|
Log::critical('Handler could not send Exception email', ['exception' => $reportE]);
|
||||||
|
}//end try
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -130,27 +120,30 @@ class ExceptionHandler extends Handler
|
||||||
* @param string $message
|
* @param string $message
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
private function getAnonymizedMessage(string $message): string
|
private static function getAnonymizedMessage(string $message): string
|
||||||
{
|
{
|
||||||
$message = \preg_replace('/^(.*)( \(SQL:.*\))$/', '$1', $message) ?? $message;
|
$message = \preg_replace('/^(.*)( \(SQL:.*\))$/', '$1', $message) ?? $message;
|
||||||
|
if ($sqlPos = \strpos($message, 'to use near')) {
|
||||||
|
$message = \mb_strcut($message, 0, $sqlPos);
|
||||||
|
}
|
||||||
return $message;
|
return $message;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Anonymize stack trace
|
* Anonymize stack trace
|
||||||
*
|
*
|
||||||
* @param \Exception $e
|
* @param \Throwable $e
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
private function getAnonymizedStackTrace(\Throwable $e): string
|
private static function getAnonymizedStackTrace(\Throwable $e): string
|
||||||
{
|
{
|
||||||
$projectPath = \realpath(\sprintf('%s/../', \app_path()));
|
$projectPath = \realpath(\sprintf('%s/../', \app_path()));
|
||||||
$traceStack = $e->getTrace();
|
$traceStack = $e->getTrace();
|
||||||
$traceStr = '';
|
$traceStr = '';
|
||||||
$maxStackStage = 0;
|
$maxStackStage = 0;
|
||||||
foreach ($traceStack as $stackStage => $stack) {
|
foreach ($traceStack as $stackStage => $stack) {
|
||||||
$maxStackStage = $stackStage;
|
$maxStackStage = $stackStage;
|
||||||
$traceStr .= \sprintf(
|
$traceStr .= \sprintf(
|
||||||
'#%s %s(%d): ',
|
'#%s %s(%d): ',
|
||||||
$stackStage,
|
$stackStage,
|
||||||
str_replace($projectPath, '', $stack['file'] ?? ''),
|
str_replace($projectPath, '', $stack['file'] ?? ''),
|
||||||
|
|
@ -159,17 +152,17 @@ class ExceptionHandler extends Handler
|
||||||
if (isset($stack['class'])) {
|
if (isset($stack['class'])) {
|
||||||
$traceStr .= "{$stack['class']}->{$stack['function']}(";
|
$traceStr .= "{$stack['class']}->{$stack['function']}(";
|
||||||
if (isset($stack['args'])) {
|
if (isset($stack['args'])) {
|
||||||
$traceStr .= $this->handleArgs($stack);
|
$traceStr .= self::handleArgs($stack);
|
||||||
}
|
}
|
||||||
$traceStr .= ")\n";
|
$traceStr .= ")\n";
|
||||||
} elseif (isset($stack['function'])) {
|
} elseif (isset($stack['function'])) {
|
||||||
$traceStr .= "{$stack['function']}(";
|
$traceStr .= "{$stack['function']}(";
|
||||||
if (isset($stack['args'])) {
|
if (isset($stack['args'])) {
|
||||||
$traceStr .= $this->handleArgs($stack);
|
$traceStr .= self::handleArgs($stack);
|
||||||
}
|
}
|
||||||
$traceStr .= ")\n";
|
$traceStr .= ")\n";
|
||||||
}
|
}
|
||||||
}
|
} //end foreach
|
||||||
$maxStackStage++;
|
$maxStackStage++;
|
||||||
$traceStr .= "#$maxStackStage {main}";
|
$traceStr .= "#$maxStackStage {main}";
|
||||||
return $traceStr;
|
return $traceStr;
|
||||||
|
|
@ -181,7 +174,7 @@ class ExceptionHandler extends Handler
|
||||||
* @param array $stack
|
* @param array $stack
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
private function handleArgs(array $stack): string
|
private static function handleArgs(array $stack): string
|
||||||
{
|
{
|
||||||
$traceArgs = '';
|
$traceArgs = '';
|
||||||
$argsCount = count($stack['args']);
|
$argsCount = count($stack['args']);
|
||||||
|
|
|
||||||
7
src/Exceptions/NoContactException.php
Normal file
7
src/Exceptions/NoContactException.php
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Kwaadpepper\ExceptionHandler\Exceptions;
|
||||||
|
|
||||||
|
class NoContactException extends \RuntimeException
|
||||||
|
{
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue