添加自定義Exception類
using System;
using System.Net;
namespace Application.Errors
{
public class RestException:Exception
{
public RestException(HttpStatusCode code,object errors=null)
{
Code = code;
Errors = errors;
}
public HttpStatusCode Code { get; }
public object Errors { get; }
}
}
添加中間件
中間件接受一個委托霎终,并且傳遞下一個委托給下一個中間件
創(chuàng)建中間件處理異常
using System;
using System.Net;
using System.Threading.Tasks;
using Application.Errors;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
namespace API.Middleware
{
public class ErrorHandlingMiddleware
{
private readonly ILogger<ErrorHandlingMiddleware> _logger;
private readonly RequestDelegate _next;
public ErrorHandlingMiddleware(RequestDelegate next,ILogger<ErrorHandlingMiddleware> logger)
{
_logger = logger;
_next = next;
}
public async Task Invoke(HttpContext context)
{
try
{
await _next(context);
}
catch(Exception ex)
{
await HandleExceptionAsync(context, ex, _logger);
}
}
private async Task HandleExceptionAsync(HttpContext context, Exception ex, ILogger<ErrorHandlingMiddleware> logger)
{
object errors = null;
switch(ex)
{
case RestException re:
logger.LogError(ex, "Rest Error");
errors = re.Errors;
context.Response.StatusCode = (int)re.Code;
break;
case Exception e:
logger.LogError(ex, "Server Error");
errors = string.IsNullOrWhiteSpace(e.Message) ? "Error" : e.Message;
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
break;
}
context.Response.ContentType = "application/json";
if(errors!=null)
{
var result = JsonConvert.SerializeObject(new
{
errors
});
await context.Response.WriteAsync(result);
}
}
}
}
在Startup類中使用中間件
app.UseMiddleware<ErrorHandlingMiddleware>();
請求響應(yīng)管道中的每一個委托都在前一個委托后執(zhí)行吠撮,所以應(yīng)當(dāng)盡量早的調(diào)用異常處理的委托
在Delete動作中拋出RestException
if (activity == null)
throw new RestException(HttpStatusCode.NotFound, new { Activity = "Not Found" });
使用postMan測試
可以得到404的返回結(jié)果和返回的json對象
客戶端異常處理
使用ReactRouter
作路由導(dǎo)航
在 /layout/ 中添加NotFound.tsx組件作為404頁面
import React from 'react';
import { Segment, Button, Header, Icon } from 'semantic-ui-react';
import { Link } from 'react-router-dom';
const NotFound = () => {
return (
<Segment placeholder>
<Header icon>
<Icon name='search' />
Oops - we've looked everywhere but couldn't find this.
</Header>
<Segment.Inline>
<Button as={Link} to='/activities' primary>
Return to Activities page
</Button>
</Segment.Inline>
</Segment>
);
};
export default NotFound;
使用axios來捕獲服務(wù)端的異常
axios.interceptors.response.use(undefined, error=> {
const { status, data, config } = error.response;
if (status === 404) {
history.push('/notfound')
}
});
```>
這里的**history** 通過 Router組件進(jìn)行注入
export const history = createBrowserHistory();
ReactDOM.render(
<Router history={history}>
<ScrollToTop>
<App />
</ScrollToTop>
</Router>
, document.getElementById('root'));
接下來添加處理其他類型異常的邏輯
添加react-toastify
npm install react-toastify
[使用文檔](https://www.npmjs.com/package/react-toastify#usage)
在index頁面添加CSS朵耕,在App頁面中添加ToastContainer
<ToastContainer position='bottom-right' />
添加其他錯誤的處理邏輯
if (error.message === "Network Error" && !error.response) {
toast.error("NetWork Error");
}
const { status,data,config } = error.response;
if (status === 404) {
history.push('/notfound')
}
if (status === 400 && config.method === 'get' && data.errors.hasOwnProperty('id')) {
history.push('/notfound')
}
if (status === 500) {
toast.error('Server error,check your terminal!')
}