Optimize exception stack of Ajax error
This commit is contained in:
parent
83330c0dfd
commit
4196a952e0
|
|
@ -3,8 +3,7 @@
|
|||
namespace App\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
|
||||
class Handler extends ExceptionHandler
|
||||
|
|
@ -13,8 +12,34 @@ class Handler extends ExceptionHandler
|
|||
* A list of the exception types that should not be reported.
|
||||
*/
|
||||
protected $dontReport = [
|
||||
HttpException::class,
|
||||
ValidationException::class,
|
||||
\Illuminate\Auth\AuthenticationException::class,
|
||||
\Illuminate\Auth\Access\AuthorizationException::class,
|
||||
\Symfony\Component\HttpKernel\Exception\HttpException::class,
|
||||
\Illuminate\Database\Eloquent\ModelNotFoundException::class,
|
||||
\Illuminate\Validation\ValidationException::class,
|
||||
PrettyPageException::class,
|
||||
];
|
||||
|
||||
protected function convertExceptionToArray(Exception $e)
|
||||
{
|
||||
return [
|
||||
'message' => $e->getMessage(),
|
||||
'exception' => true,
|
||||
'trace' => collect($e->getTrace())
|
||||
->map(function ($trace) {
|
||||
return Arr::only($trace, ['file', 'line']);
|
||||
})
|
||||
->filter(function ($trace) {
|
||||
return Arr::has($trace, 'file');
|
||||
})
|
||||
->map(function ($trace) {
|
||||
$trace['file'] = str_replace(base_path().DIRECTORY_SEPARATOR, '', $trace['file']);
|
||||
return $trace;
|
||||
})
|
||||
->filter(function ($trace) {
|
||||
return \Illuminate\Support\Str::startsWith($trace['file'], 'app');
|
||||
})
|
||||
->values(),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,20 +37,28 @@ export async function walkFetch(request: Request): Promise<any> {
|
|||
if (response.ok) {
|
||||
return body
|
||||
}
|
||||
let message = body.message
|
||||
|
||||
// Process validation errors from Laravel.
|
||||
if (response.status === 422) {
|
||||
// Process validation errors from Laravel.
|
||||
const { errors }: { message: string, errors: { [field: string]: string[] } } = body
|
||||
return {
|
||||
code: 1,
|
||||
message: Object.keys(errors).map(field => errors[field][0])[0],
|
||||
}
|
||||
} else if (response.status === 403) {
|
||||
showModal(body.message, undefined, 'warning')
|
||||
showModal(message, undefined, 'warning')
|
||||
return
|
||||
}
|
||||
|
||||
throw new HTTPError(body.message || body, cloned)
|
||||
if (body.exception && Array.isArray(body.trace)) {
|
||||
const trace = (body.trace as { file: string, line: number }[])
|
||||
.map((t, i) => `[${i + 1}] ${t.file}#L${t.line}`)
|
||||
.join('\n')
|
||||
message = `${message}\n<details>${trace}</details>`
|
||||
}
|
||||
|
||||
throw new HTTPError(message || body, cloned)
|
||||
} catch (error) {
|
||||
emit('fetchError', error)
|
||||
showAjaxError(error)
|
||||
|
|
|
|||
|
|
@ -148,6 +148,21 @@ test('process backend errors', async () => {
|
|||
},
|
||||
clone: () => ({}),
|
||||
})
|
||||
.mockResolvedValueOnce({
|
||||
status: 500,
|
||||
headers: new Map([['Content-Type', 'application/json']]),
|
||||
json() {
|
||||
return Promise.resolve({
|
||||
message: 'fake exception',
|
||||
exception: true,
|
||||
trace: [
|
||||
{ file: 'k.php', line: 2 },
|
||||
{ file: 'v.php', line: 3 },
|
||||
],
|
||||
})
|
||||
},
|
||||
clone: () => ({}),
|
||||
})
|
||||
|
||||
const result: {
|
||||
code: number,
|
||||
|
|
@ -158,6 +173,11 @@ test('process backend errors', async () => {
|
|||
|
||||
await net.walkFetch({ headers: new Headers() } as Request)
|
||||
expect(showModal).toBeCalledWith('forbidden', undefined, 'warning')
|
||||
|
||||
await net.walkFetch({ headers: new Headers() } as Request)
|
||||
expect(showAjaxError.mock.calls[0][0].message).toBe(
|
||||
'fake exception\n<details>[1] k.php#L2\n[2] v.php#L3</details>'
|
||||
)
|
||||
})
|
||||
|
||||
test('inject to Vue instance', () => {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
## Tweaked
|
||||
|
||||
- Push notifications to queue for performance.
|
||||
- Optimized exception stack of Ajax error.
|
||||
|
||||
## Fixed
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
## 调整
|
||||
|
||||
- 发送通知时将任务推送到队列
|
||||
- 优化 Ajax 中的错误显示
|
||||
|
||||
## 修复
|
||||
|
||||
|
|
|
|||
18
tests/ExceptionsTests/HandlerTest.php
Normal file
18
tests/ExceptionsTests/HandlerTest.php
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace Tests;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class HandlerTest extends TestCase
|
||||
{
|
||||
public function testRenderAjaxException()
|
||||
{
|
||||
$json = $this->get('/abc', ['Accept' => 'application/json'])->decodeResponseJson();
|
||||
$this->assertIsString($json['message']);
|
||||
$this->assertTrue($json['exception']);
|
||||
$this->assertTrue(collect($json['trace'])->every(function ($trace) {
|
||||
return Str::startsWith($trace['file'], 'app') && is_int($trace['line']);
|
||||
}));
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user