我有一个用C#编写的MVC 5后端.它提供用Razor编写的MVC视图以及一些Angular 2页面.
从客户端调用服务器时,处理潜在错误的最佳方法是什么?我真的想建立一个强大的模式,适用于所有情况.以下是我到目前为止所尝试的内容.
后端C#代码:
public class MyController : Controller
{
[HttpGet]
public ActionResult GetUsers()
{
try
{
// Lot of fancy server code ...
throw new Exception("Dummy error");
return GetCompressedResult(json);
}
catch (Exception ex)
{
throw new HttpException(501, ex.Message);
}
}
private FileContentResult GetCompressedResult(string json)
{
// Transform to byte array
var bytes = Encoding.UTF8.GetBytes(json);
// Compress array
var compressedBytes = bytes.Compress();
HttpContext.Response.AppendHeader("Content-encoding", "gzip");
return new FileContentResult(compressedBytes, "application/json");
}
}
客户端Angular 2代码:
public loadDataFromServer() {
let response = this.http.get(this.urlGetData)
.map((res: Response) => res.json())
.catch(this.handleError);
response.subscribe(response => {
// Process valid result ...
},
err => { console.error(err); }
);
};
private handleError(error: Response | any) {
let errMsg: string;
if (error instanceof Response) {
const body = JSON.parse(JSON.stringify(error || null))
const err = body.error || JSON.stringify(body);
errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
} else {
errMsg = error.message ? error.message : error.toString();
}
console.error(errMsg);
return Observable.throw(errMsg);
}
这是handleError方法处理的错误对象的打印屏幕:
这一切都提出了一些问题:
>从服务器抛出自定义HttpException是否正确?
> handleError方法是正确的还是太复杂?
>在客户端,我希望看到自定义错误消息,但目前它只是在一个非常难以解析的HTML“blob”中找到.
>客户端错误处理在获取调用和订阅操作中是否必要?
最佳答案 我目前的建议是让服务器用Json对象响应所有处理的异常.
在客户端,我在处理有效结果之前检查结果对象是否有可能的错误属性.
handleResponseError方法将解析类型化的Response对象并抛出可观察的消息.但至少我的浏览器(Chrome 57)似乎会自动将响应错误记录到控制台.因此,如果订户不需要针对不同错误的特定额外处理,则订户不需要针对错误对象的额外操作.
如果有更好的方法,请反馈!
后端C#代码:
public class MyController : Controller
{
[HttpGet]
public ActionResult GetUsers()
{
try
{
// Lot of fancy server code ...
throw new ArgumentException("Dummy error");
// Normal return of result ...
}
catch (Exception ex)
{
return Json(new { error = $"{ex.GetType().FullName}: '{ex.Message}'" }, JsonRequestBehavior.AllowGet);
}
}
}
客户端Angular 2代码:
public loadDataFromServer() {
let response = this.http.get(this.urlGetData)
.map((res: Response) => res.json())
.catch(this.handleResponseError);
response.subscribe(result => {
if (result.error) {
this.displayJsonError(this.urlGetUsers, result.error);
}
else {
// Process valid result
}
});
};
private handleResponseError(value: Response | any) {
let errorMessage = value.toString();
let response = value as Response;
if (response) {
errorMessage = `${response.status}: ${response.statusText}\n${response.toString()}`;
}
if (value.error) {
errorMessage = value.error;
}
if (value.message) {
errorMessage = value.message;
}
return Observable.throw(errorMessage);
}
private displayJsonError(url: string, error: string) {
console.error(`Call to '${url}' failed with ${error}`);
}