Handler.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. <?php
  2. namespace app\common\exceptions;
  3. use app\common\components\ApiController;
  4. use app\common\helpers\Client;
  5. use app\common\helpers\Url;
  6. use app\common\traits\JsonTrait;
  7. use app\common\traits\MessageTrait;
  8. use app\framework\Support\Facades\Log;
  9. use app\frontend\modules\member\services\factory\MemberFactory;
  10. use Exception;
  11. use Illuminate\Auth\AuthenticationException;
  12. use Illuminate\Database\QueryException;
  13. use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
  14. use Ixudra\Curl\Facades\Curl;
  15. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  16. class Handler extends ExceptionHandler
  17. {
  18. use JsonTrait;
  19. use MessageTrait;
  20. private $isRendered;
  21. /**
  22. * A list of the exception types that should not be reported.
  23. *
  24. * @var array
  25. */
  26. protected $dontReport = [
  27. \Illuminate\Auth\AuthenticationException::class,
  28. \Illuminate\Auth\Access\AuthorizationException::class,
  29. \Symfony\Component\HttpKernel\Exception\HttpException::class,
  30. \Illuminate\Database\Eloquent\ModelNotFoundException::class,
  31. \Illuminate\Session\TokenMismatchException::class,
  32. \Illuminate\Validation\ValidationException::class,
  33. \EasyWeChat\Core\Exceptions\HttpException::class,
  34. \EasyWeChat\Core\Exceptions\InvalidArgumentException::class,
  35. NotFoundException::class,
  36. MemberNotLoginException::class,
  37. ShopException::class,
  38. //QueryException::class,
  39. ];
  40. /**
  41. * Report or log an exception.
  42. *
  43. * This is a great spot to send exceptions to Sentry, Bugsnag, etc.
  44. * @param Exception $exception
  45. * @throws Exception
  46. */
  47. public function report(Exception $exception)
  48. {
  49. if ($this->shouldntReport($exception)) {
  50. return;
  51. }
  52. try {
  53. // 记录错误日志
  54. if (!app()->runningInConsole()) {
  55. Log::error('http parameters', request()->input());
  56. }
  57. Log::error($exception);
  58. //生产环境发送错误报告
  59. /*if (app()->environment() == 'production') {
  60. if(class_exists(Curl::class)){
  61. Curl::to('https://dev9.yunzmall.com/api/error-log/upload')->withData([
  62. 'post_data[domain]' => request()->getSchemeAndHttpHost(),
  63. 'post_data[title]' => '',
  64. 'post_data[content]' =>
  65. json_encode([
  66. 'file' => $exception->getFile(),
  67. 'line' => $exception->getLine(),
  68. 'message' => $exception->getMessage(),
  69. 'requestData' => request()->input()
  70. ], true)
  71. ])->post();
  72. }
  73. }*/
  74. } catch (Exception $ex) {
  75. dump($exception);
  76. dd($ex);
  77. }
  78. parent::report($exception);
  79. }
  80. /**
  81. * Render an exception into an HTTP response.
  82. *
  83. * @param \Illuminate\Http\Request $request
  84. * @param \Exception $exception
  85. * @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response|\Symfony\Component\HttpFoundation\Response
  86. */
  87. public function render($request, Exception $exception)
  88. {
  89. if ($this->isRendered) {
  90. return;
  91. }
  92. $this->isRendered = true;
  93. // 会员登录
  94. if ($exception instanceof MemberNotLoginException) {
  95. return $this->renderMemberNotLoginException($exception);
  96. }
  97. //后台登录异常--修改密码,单点登录
  98. if ($exception instanceof AuthenticationException) {
  99. return $this->unauthenticated($request, $exception);
  100. }
  101. if ($exception instanceof MemberErrorMsgException) {
  102. return $this->renderLoginErrorMsg($exception);
  103. }
  104. // sql异常啦
  105. /*if ($exception instanceof QueryException) {
  106. return $this->renderQueryException($exception);
  107. }*/
  108. //接口异常
  109. if ($exception instanceof ApiException) {
  110. return $this->errorJson($exception->getMessage(), $exception->getData());
  111. }
  112. // 商城异常
  113. if ($exception instanceof ShopException || $exception instanceof AppException) {
  114. return $this->renderShopException($exception);
  115. }
  116. // 404
  117. if ($exception instanceof NotFoundHttpException) {
  118. return $this->renderNotFoundException($exception);
  119. }
  120. /*if (app()->environment() === 'production') {
  121. return $this->renderBackendError($exception);
  122. }*/
  123. //开发模式异常
  124. if (app()->environment() !== 'production') {
  125. return $this->renderExceptionWithWhoops($exception);
  126. }
  127. //api异常
  128. if (\YunShop::isApi()) {
  129. return $this->errorJson($exception->getMessage());
  130. }
  131. //默认异常
  132. if ($this->isHttpException($exception)) {
  133. return $this->renderHttpException($exception);
  134. }
  135. return parent::render($request, $exception);
  136. }
  137. /**
  138. * Convert an authentication exception into an unauthenticated response.
  139. *
  140. * @param \Illuminate\Http\Request $request
  141. * @param \Illuminate\Auth\AuthenticationException $exception
  142. * @return \Illuminate\Http\Response
  143. */
  144. protected function unauthenticated($request, AuthenticationException $exception)
  145. {
  146. if (strpos($_SERVER['REQUEST_URI'], '/admin/shop') !== false) {
  147. return redirect()->guest('/admin.html');
  148. }
  149. $login_path = [
  150. 'admin' => '/#/login',
  151. ];
  152. $url = empty($guard) ? '/login' : (isset($login_path[$guard]) ? $login_path[$guard] : '/login');
  153. return response()->json(['status' => 0,'data'=>['login_status' => 1, 'login_url' => $url]]);
  154. }
  155. protected function renderShopException(ShopException $exception)
  156. {
  157. if (request()->isFrontend() || request()->ajax()) {
  158. return $this->errorJson($exception->getMessage(), $exception->getData());
  159. }
  160. $redirect = $exception->redirect ?: '';
  161. return $this->message($exception->getMessage(), $redirect, 'error');
  162. }
  163. /**
  164. * Render an exception using Whoops.
  165. *
  166. * @param \Exception $e
  167. * @return \Illuminate\Http\Response
  168. */
  169. protected function renderExceptionWithWhoops(Exception $e)
  170. {
  171. $whoops = new \Whoops\Run;
  172. $whoops->pushHandler(new \Whoops\Handler\PrettyPageHandler());
  173. if (method_exists($e, 'getStatusCode')) {
  174. return new \Illuminate\Http\Response(
  175. $whoops->handleException($e),
  176. $e->getStatusCode(),
  177. $e->getHeaders()
  178. );
  179. }
  180. return new \Illuminate\Http\Response(
  181. $whoops->handleException($e)
  182. );
  183. }
  184. protected function renderNotFoundException(NotFoundHttpException $exception)
  185. {
  186. if (\Yunshop::isPHPUnit()) {
  187. return $exception->getMessage();
  188. }
  189. if (\Yunshop::isApi() || request()->ajax()) {
  190. return $this->errorJson('不存在的接口');
  191. }
  192. $redirect = $exception->redirect ?: '';
  193. return $this->message('不存在的页面', $redirect, 'error');
  194. }
  195. protected function renderMemberNotLoginException(MemberNotLoginException $exception)
  196. {
  197. $data = $exception->getData();
  198. if (request()->isFrontend() || request()->ajax()) {
  199. $arr = [];
  200. $split_data = explode('&', $exception->getData());
  201. foreach ($split_data as $val) {
  202. $temp = explode('=', $val);
  203. $arr[$temp[0]] = $temp[1];
  204. }
  205. $type = $arr['type']?:request()->type;
  206. $i = $arr['i']?:request()->i;
  207. $mid = $arr['mid']?:request()->mid;
  208. $scope = 'login';
  209. $extra = '';
  210. if (!is_null(\config('hflive'))) {
  211. $extra = ['hflive' => \config('hflive')];
  212. }
  213. if (Client::setWechatByMobileLogin($type)) {
  214. $type = 5;
  215. }
  216. if (Client::getType() == 8 && (app('plugins')->isEnabled('alipay-onekey-login'))) {
  217. $type = 8;
  218. }
  219. //清除session,注销会员需要清除
  220. setcookie('Yz-Token', '', time() - 3600);
  221. setcookie('Yz-appToken', '', time() - 3600);
  222. setcookie(session_name(), '',time() - 3600, '/');
  223. setcookie(session_name(), '',time() - 3600, '/addons/yun_shop');
  224. session_destroy();
  225. $queryString = ['type' => $type, 'i' => $i, 'mid' => $mid, 'scope' => $scope];
  226. $data = ['login_status' => 0, 'login_url' => Url::absoluteApi('member.login.index', $queryString), 'extra' => $extra];
  227. if (in_array($type, [MemberFactory::LOGIN_MOBILE, MemberFactory::LOGIN_APP_YDB, MemberFactory::LOGIN_Native, MemberFactory::LOGIN_APP_ANCHOR, MemberFactory::LOGIN_APP_LSP_WALLET])) {
  228. $data = ['login_status' => 1, 'login_url' => '', 'type' => $type, 'i' => \YunShop::app()->uniacid, 'mid' => $mid, 'scope' => $scope, 'extra' => $extra];
  229. }
  230. }
  231. return $this->errorJson('请登录', $data);
  232. }
  233. protected function renderLoginErrorMsg(MemberErrorMsgException $exception)
  234. {
  235. $img = resource_get('static/warning.png');
  236. echo <<<EOT
  237. <div style="width:100%; ">
  238. <div style="margin-top: 300px;">&nbsp;</div>
  239. <div style="margin: auto; text-align: center; width:60%;"><img src="{$img}"> </div>
  240. <div style="padding-top: 20px;margin: auto; text-align: center; width:60%; font-size:40px; height: 40px; line-height: 40px;">{$exception->getMessage()}</div>
  241. </div>
  242. EOT;
  243. exit;
  244. }
  245. protected function renderBackendError(Exception $exception)
  246. {
  247. $img = resource_get('static/500error.png');
  248. Log::error($exception->getMessage().' error file in '.$exception->getFile().'('.$exception->getLine().')');
  249. if (request()->isFrontend() || request()->ajax()) {
  250. return $this->errorJson('数据错误');
  251. }
  252. echo <<<EOT
  253. <div style="width:100%; ">
  254. <div style="margin-top: 200px;">&nbsp;</div>
  255. <div style="margin: auto; text-align: center; width:60%;"><img src="{$img}"></div>
  256. </div>
  257. EOT;
  258. exit;
  259. }
  260. protected function renderQueryException(QueryException $exception)
  261. {
  262. \Log::error('-----数据库异常-----', $exception->getMessage());
  263. }
  264. }