diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php new file mode 100644 index 0000000..3bffe95 --- /dev/null +++ b/app/Exceptions/Handler.php @@ -0,0 +1,37 @@ +environment('local') || app()->environment('production')) { + $this->sendSlackException($e); + } + + parent::report($e); // 로그는 그대로 + } + + protected function sendSlackException(Throwable $e): void + { + try { + $url = env('LOG_SLACK_WEBHOOK_URL'); + + if (!$url) return; + + Http::post($url, [ + 'text' => "*🚨 Laravel 예외 발생!*\n" . + "• 메시지: `{$e->getMessage()}`\n" . + "• 위치: `{$e->getFile()}:{$e->getLine()}`\n" . + "• 시간: " . now()->toDateTimeString() + ]); + } catch (Throwable $ex) { + logger()->error('슬랙 전송 실패', ['message' => $ex->getMessage()]); + } + } +} diff --git a/bootstrap/app.php b/bootstrap/app.php index 205d5ef..7d73d90 100644 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -1,14 +1,18 @@ withRouting( web: __DIR__.'/../routes/web.php', api: __DIR__.'/../routes/api.php', @@ -16,18 +20,20 @@ health: '/up', ) ->withMiddleware(function (Middleware $middleware) { - - // CORS 미들웨어 추가 $middleware->append(CorsMiddleware::class); $middleware->alias([ - 'auth.apikey' => ApiKeyMiddleware::class, // Api Key 인증 미들웨어 - 'swagger.auth' => CheckSwaggerAuth::class, // Swagger 인증 미들웨어 - 'permission' => CheckPermission::class, // 권한확인 미들웨어 + 'auth.apikey' => ApiKeyMiddleware::class, + 'swagger.auth' => CheckSwaggerAuth::class, + 'permission' => CheckPermission::class, ]); - }) ->withExceptions(function (Exceptions $exceptions) { - // - })->create(); + // 이건 비워두세요 + }) + ->create(); +// 🔥 핵심: create() 이후에 반드시 등록 +$app->singleton(ExceptionHandler::class, Handler::class); + +return $app; diff --git a/composer.json b/composer.json index b55f91c..fc1e8e1 100644 --- a/composer.json +++ b/composer.json @@ -20,7 +20,6 @@ "laravel/pint": "^1.13", "laravel/sail": "^1.41", "mockery/mockery": "^1.6", - "nunomaduro/collision": "^8.6", "phpunit/phpunit": "^11.5.3" }, "autoload": { diff --git a/composer.lock b/composer.lock index 737f63b..99f7b24 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "58ca6a824fd96845d637d869a136b0b0", + "content-hash": "c85aa435b860ec1190921846b8891208", "packages": [ { "name": "bacon/bacon-qr-code", @@ -6827,77 +6827,6 @@ }, "time": "2024-11-21T13:46:39+00:00" }, - { - "name": "filp/whoops", - "version": "2.18.3", - "source": { - "type": "git", - "url": "https://github.com/filp/whoops.git", - "reference": "59a123a3d459c5a23055802237cb317f609867e5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/filp/whoops/zipball/59a123a3d459c5a23055802237cb317f609867e5", - "reference": "59a123a3d459c5a23055802237cb317f609867e5", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0", - "psr/log": "^1.0.1 || ^2.0 || ^3.0" - }, - "require-dev": { - "mockery/mockery": "^1.0", - "phpunit/phpunit": "^7.5.20 || ^8.5.8 || ^9.3.3", - "symfony/var-dumper": "^4.0 || ^5.0" - }, - "suggest": { - "symfony/var-dumper": "Pretty print complex values better with var-dumper available", - "whoops/soap": "Formats errors as SOAP responses" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Whoops\\": "src/Whoops/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Filipe Dobreira", - "homepage": "https://github.com/filp", - "role": "Developer" - } - ], - "description": "php error handling for cool kids", - "homepage": "https://filp.github.io/whoops/", - "keywords": [ - "error", - "exception", - "handling", - "library", - "throwable", - "whoops" - ], - "support": { - "issues": "https://github.com/filp/whoops/issues", - "source": "https://github.com/filp/whoops/tree/2.18.3" - }, - "funding": [ - { - "url": "https://github.com/denis-sokolov", - "type": "github" - } - ], - "time": "2025-06-16T00:02:10+00:00" - }, { "name": "hamcrest/hamcrest-php", "version": "v2.1.1", @@ -7303,105 +7232,6 @@ ], "time": "2025-07-05T12:25:42+00:00" }, - { - "name": "nunomaduro/collision", - "version": "v8.8.2", - "source": { - "type": "git", - "url": "https://github.com/nunomaduro/collision.git", - "reference": "60207965f9b7b7a4ce15a0f75d57f9dadb105bdb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/collision/zipball/60207965f9b7b7a4ce15a0f75d57f9dadb105bdb", - "reference": "60207965f9b7b7a4ce15a0f75d57f9dadb105bdb", - "shasum": "" - }, - "require": { - "filp/whoops": "^2.18.1", - "nunomaduro/termwind": "^2.3.1", - "php": "^8.2.0", - "symfony/console": "^7.3.0" - }, - "conflict": { - "laravel/framework": "<11.44.2 || >=13.0.0", - "phpunit/phpunit": "<11.5.15 || >=13.0.0" - }, - "require-dev": { - "brianium/paratest": "^7.8.3", - "larastan/larastan": "^3.4.2", - "laravel/framework": "^11.44.2 || ^12.18", - "laravel/pint": "^1.22.1", - "laravel/sail": "^1.43.1", - "laravel/sanctum": "^4.1.1", - "laravel/tinker": "^2.10.1", - "orchestra/testbench-core": "^9.12.0 || ^10.4", - "pestphp/pest": "^3.8.2", - "sebastian/environment": "^7.2.1 || ^8.0" - }, - "type": "library", - "extra": { - "laravel": { - "providers": [ - "NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider" - ] - }, - "branch-alias": { - "dev-8.x": "8.x-dev" - } - }, - "autoload": { - "files": [ - "./src/Adapters/Phpunit/Autoload.php" - ], - "psr-4": { - "NunoMaduro\\Collision\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nuno Maduro", - "email": "enunomaduro@gmail.com" - } - ], - "description": "Cli error handling for console/command-line PHP applications.", - "keywords": [ - "artisan", - "cli", - "command-line", - "console", - "dev", - "error", - "handling", - "laravel", - "laravel-zero", - "php", - "symfony" - ], - "support": { - "issues": "https://github.com/nunomaduro/collision/issues", - "source": "https://github.com/nunomaduro/collision" - }, - "funding": [ - { - "url": "https://www.paypal.com/paypalme/enunomaduro", - "type": "custom" - }, - { - "url": "https://github.com/nunomaduro", - "type": "github" - }, - { - "url": "https://www.patreon.com/nunomaduro", - "type": "patreon" - } - ], - "time": "2025-06-25T02:12:12+00:00" - }, { "name": "phar-io/manifest", "version": "2.0.4", diff --git a/routes/api.php b/routes/api.php index 1b561bf..238bbd5 100644 --- a/routes/api.php +++ b/routes/api.php @@ -9,6 +9,11 @@ use App\Http\Controllers\Api\V1\FileController; use App\Http\Controllers\Api\V1\ProductController; +// error test +Route::get('/test-error', function () { + throw new \Exception('슬랙 전송 테스트 예외'); +}); + // V1 초기 개발 Route::prefix('v1')->group(function () {