You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

263 lines
7.8 KiB
PHP

<?php
namespace App\Exceptions;
use App\Models\Setting;
use Carbon\Carbon;
use ErrorException;
use Exception;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Session\TokenMismatchException;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
use Throwable;
class Handler extends ExceptionHandler
{
/**
* A list of the exception types that are not reported.
*
* @var array<int, class-string<Throwable>>
*/
protected $dontReport = [
//
];
/**
* A list of the inputs that are never flashed for validation exceptions.
*
* @var array<int, string>
*/
protected $dontFlash = [
'current_password',
'password',
'password_confirmation',
];
/**
* Register the exception handling callbacks for the application.
*
* @return void
*/
public function register()
{
$this->reportable(function (Throwable $e) {
//
});
}
/**
* Report or log an exception.
*
* @param Throwable $e
* @return void
* @throws Throwable
*/
/*
public function report(Throwable $e)
{
if (app()->bound('sentry') && $this->shouldReport($e)) {
app('sentry')->captureException($e);
}
parent::report($e);
}
*/
/**
* Render an exception into an HTTP response.
*
* @param Request $request
* @param Throwable $exception
* @return RedirectResponse|Response
* @throws Throwable
*/
public function render($request, Throwable $exception)
{
DB::rollBack();
// Page Header
$page = [
'code' => 'error',
'title' => '',
'subTitle' => '',
'description' => '',
'link' => '/',
'is_main' => true
];
$pages = config('pages');
if ($request->ajax() || $request->wantsJson() || $request->expectsJson()) {
$response = $this->errorJson($exception);
if ($response !== false) {
return $response;
}
}
$errorCode = 500;
if (method_exists($exception, 'getStatusCode')) {
$errorCode = $exception->getStatusCode();
}
$data = [
'breadcrumbs'=>[],
'pageheader'=>[
'code' => 'exception',
'title' => 'Exception',
'icon' => 'fa-exclamation-triangle',
'description' => '',
'link' => ''
],
'errorCode' => $errorCode,
'exception' => $exception,
'now' => (string)Carbon::now(),
'page' => $page,
'pages' => $pages,
'settings' => $this->setSettings()
];
if ($exception instanceof UnauthorizedHttpException
|| $exception instanceof AuthenticationException
|| $exception instanceof AuthorizationException
|| $exception instanceof VerifyCsrfToken
|| $exception instanceof TokenMismatchException) {
return redirect()->route('cms.login');
}
return response()->view('errors', $data, $errorCode);
}
/**
* Render an exception into an HTTP response.
*
* @param Throwable $exception
* @return bool|JsonResponse
* @throws Throwable
*/
private function errorJson(Throwable $exception) {
$errorCode = 500;
if (method_exists($exception, 'getStatusCode')) {
$errorCode = $exception->getStatusCode();
}
if ($errorCode == 503) {
$messageText = "서버 점검중입니다.";
$result = [
"status" => $errorCode,
"message" => $messageText,
"success" => false,
"data" => null,
"errors" => [ "message" => [ $messageText ] ]
];
$headers = [];
return response()->json($result, $errorCode, $headers, JSON_UNESCAPED_UNICODE);
}
if ($exception instanceof UnauthorizedHttpException || $exception instanceof AuthenticationException || $exception instanceof AuthorizationException) {
$errorCode = 401;
$result = [
"status" => $errorCode,
"message" => "인증정보가 없습니다.",
"success" => false,
"data" => null,
"errors" => [ "message" => [ $exception->getMessage() ] ]
];
logger($result);
$headers = [];
return response()->json($result, $errorCode, $headers, JSON_UNESCAPED_UNICODE);
} else if ($exception instanceof ValidationException ) {
$result = [
"status" => $errorCode,
"message" => "유효성 검사가 실패했습니다.",
"success" => false,
"data" => null,
"errors" => $exception->validator->messages()->messages()
];
logger($result);
$headers = [];
return response()->json($result, $errorCode, $headers, JSON_UNESCAPED_UNICODE);
} else if ($exception instanceof AccessDeniedHttpException) {
$result = [
"status" => $errorCode,
"message" => "접근권한이 없습니다.",
"success" => false,
"data" => null,
"errors" => [ "message" => [ 'AccessDenied' ] ]
];
logger($result);
$headers = [];
return response()->json($result, $errorCode, $headers, JSON_UNESCAPED_UNICODE);
} else if ($exception instanceof TokenMismatchException) {
$errorCode = 419;
$result = [
"status" => $errorCode,
"message" => "인증토근이 일치하지 않습니다.",
"success" => false,
"data" => null,
"errors" => [ "message" => [ 'CSRF Token Mismatch' ] ]
];
logger($result);
$headers = [];
return response()->json($result, $errorCode, $headers, JSON_UNESCAPED_UNICODE);
} else if ($exception instanceof Exception) {
$message = $exception->getMessage();
if (!$message) {
$message = sprintf("[%d] 서버 에러", $errorCode);
}
$result = [
"status" => $errorCode,
"message" => "서버 에러",
"success" => false,
"data" => null,
"errors" => ["message" => [$message]]
];
logger($result);
if(!$exception->getMessage() || $errorCode != 404) {
logger($exception->getFile(). " : " . $exception->getLine());
logger($exception->getTraceAsString());
}
$headers = [];
return response()->json($result, $errorCode, $headers, JSON_UNESCAPED_UNICODE);
}
return false;
}
private function setSettings() {
// 전역변수 설정
$_settings = Setting::all();
$settings = [];
if ($_settings) {
foreach ($_settings as $row) {
$settings[$row['key']] = $row['value'];
}
}
//logger($settings);
return (object)$settings;
}
}