Complete api errors standardization

This commit is contained in:
Bubka 2020-01-27 21:13:21 +01:00
parent 17f43b6f68
commit e0207b096d
8 changed files with 32 additions and 75 deletions

View File

@ -49,44 +49,7 @@ class Handler extends ExceptionHandler
* @return \Illuminate\Http\Response * @return \Illuminate\Http\Response
*/ */
public function render($request, Exception $exception) public function render($request, Exception $exception)
{ {
// if (!($exception instanceof ValidationException)) {
// if ($exception instanceof \Illuminate\Auth\AuthenticationException) {
// $response['message'] = (string)$exception->getMessage();
// $response['status_code'] = Response::HTTP_UNAUTHORIZED;
// } else if ($exception instanceof HttpException) {
// $response['message'] = Response::$statusTexts[$exception->getStatusCode()];
// $response['status_code'] = $exception->getStatusCode();
// } else if ($exception instanceof ModelNotFoundException) {
// $response['message'] = Response::$statusTexts[Response::HTTP_NOT_FOUND];
// $response['status_code'] = Response::HTTP_NOT_FOUND;
// }
// else {
// $response = [
// 'message' => (string)$exception->getMessage(),
// 'status_code' => $exception->getStatusCode(),
// ];
// }
// if ($this->isDebugMode()) {
// $response['debug'] = [
// 'exception' => get_class($exception),
// 'trace' => $exception->getTrace()
// ];
// // return parent::render($request, $exception);
// }
// return response()->json($response, $response['status_code']);
// }
// return parent::render($request, $exception);
if ( $request->wantsJson() ) { if ( $request->wantsJson() ) {
return $this->handleApiException($request, $exception); return $this->handleApiException($request, $exception);
@ -95,7 +58,6 @@ class Handler extends ExceptionHandler
return parent::render($request, $exception); return parent::render($request, $exception);
} }
} }
@ -108,6 +70,11 @@ class Handler extends ExceptionHandler
*/ */
private function handleApiException($request, Exception $exception) private function handleApiException($request, Exception $exception)
{ {
$debug = [
'exception' => get_class($exception),
'trace' => $exception->getTrace(),
];
$exception = $this->prepareException($exception); $exception = $this->prepareException($exception);
if ($exception instanceof \Illuminate\Http\Exception\HttpResponseException) { if ($exception instanceof \Illuminate\Http\Exception\HttpResponseException) {
@ -122,7 +89,7 @@ class Handler extends ExceptionHandler
$exception = $this->convertValidationExceptionToResponse($exception, $request); $exception = $this->convertValidationExceptionToResponse($exception, $request);
} }
return $this->customApiResponse($exception); return $this->customApiResponse($exception, $debug);
} }
@ -132,7 +99,7 @@ class Handler extends ExceptionHandler
* @param \Exception $exception * @param \Exception $exception
* @return \Illuminate\Http\JsonResponse * @return \Illuminate\Http\JsonResponse
*/ */
private function customApiResponse($exception) private function customApiResponse($exception, $debug)
{ {
if (method_exists($exception, 'getStatusCode')) { if (method_exists($exception, 'getStatusCode')) {
$statusCode = $exception->getStatusCode(); $statusCode = $exception->getStatusCode();
@ -172,11 +139,7 @@ class Handler extends ExceptionHandler
if (env('APP_DEBUG')) { if (env('APP_DEBUG')) {
$response['debug'] = [ $response['debug'] = $debug;
// 'exception' => get_class($exception),
// 'code' => $exception->getCode(),
// 'trace' => $exception->getTrace(),
];
} }
return response()->json($response, $statusCode); return response()->json($response, $statusCode);

18
resources/js/api.js vendored
View File

@ -32,25 +32,23 @@ Vue.axios.interceptors.request.use(function (request) {
Vue.axios.interceptors.response.use(response => response, error => { Vue.axios.interceptors.response.use(response => response, error => {
// Return the error when it has been asked // Return the error when we need to handle it at component level
if( error.config.hasOwnProperty('returnError') && error.config.returnError === true ) { if( error.config.hasOwnProperty('returnError') && error.config.returnError === true ) {
return Promise.reject(error); return Promise.reject(error);
} }
// Return the error for form validation at component level
if( error.response.status === 422 ) { if( error.response.status === 422 ) {
return Promise.reject(error); return Promise.reject(error);
} }
// Otherwise we push to the error views // Otherwise we push to a specific or generic error view
if ( error.response.status === 404 ) { let routeName = 'genericError'
router.push({name: '404'}) if ( error.response.status === 401 ) routeName = 'login'
throw new Vue.axios.Cancel('pushed to 404'); if ( error.response.status === 404 ) routeName = '404'
}
else {
router.push({ name: 'genericError', params: { err: error.response } })
throw new Vue.axios.Cancel('pushed to generic error');
}
router.push({ name: routeName, params: { err: error.response } })
throw new Vue.axios.Cancel();
}) })

View File

@ -176,13 +176,13 @@
}, },
// beforeRouteEnter (to, from, next) { beforeRouteEnter (to, from, next) {
// if ( ! localStorage.getItem('jwt')) { if ( ! localStorage.getItem('jwt')) {
// return next('login') return next('login')
// } }
// next() next()
// } }
} }
</script> </script>

View File

@ -67,7 +67,7 @@
handleSubmit(e) { handleSubmit(e) {
e.preventDefault() e.preventDefault()
this.form.post('/api/login') this.form.post('/api/login', {returnError: true})
.then(response => { .then(response => {
localStorage.setItem('user',response.data.message.name) localStorage.setItem('user',response.data.message.name)
localStorage.setItem('jwt',response.data.message.token) localStorage.setItem('jwt',response.data.message.token)

View File

@ -53,7 +53,7 @@
handleSubmit(e) { handleSubmit(e) {
e.preventDefault() e.preventDefault()
this.form.post('/api/password/email') this.form.post('/api/password/email', {returnError: true})
.then(response => { .then(response => {
this.response = response.data.status this.response = response.data.status

View File

@ -70,7 +70,7 @@
handleSubmit(e) { handleSubmit(e) {
e.preventDefault() e.preventDefault()
this.form.post('/api/password/reset') this.form.post('/api/password/reset', {returnError: true})
.then(response => { .then(response => {
this.$router.go('/'); this.$router.go('/');

View File

@ -75,7 +75,7 @@
this.errorMessage = '' this.errorMessage = ''
this.response = '' this.response = ''
this.form.patch('/api/password') this.form.patch('/api/password', {returnError: true})
.then(response => { .then(response => {
this.response = response.data.message this.response = response.data.message

View File

@ -75,14 +75,10 @@
} }
}, },
mounted: function() { async mounted() {
this.form.get('/api/user') const { data } = await this.form.get('/api/user')
.then(response => {
this.form.fill(response.data) this.form.fill(data)
})
.catch(error => {
this.$router.push({ name: 'genericError', params: { err: error.response } });
});
}, },
methods : { methods : {
@ -92,7 +88,7 @@
this.errorMessage = '' this.errorMessage = ''
this.response = '' this.response = ''
this.form.patch('/api/user') this.form.patch('/api/user', {returnError: true})
.then(response => { .then(response => {
this.response = response.data.message this.response = response.data.message