I have a MVC 5 backend written in C#. It serves MVC views written in Razor and also some Angular 2 pages.
What is the best way to handle potential errors when calling server from client? I really would like to establish a pattern that is robust and works in all situations. Below is what I have tried so far.
Backend C# code:
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");
}
}
Client side Angular 2 code:
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);
}
This is a printscreen of the error object processed by handleError method:
This all raises some questions:
My current suggestion is to let server respond with Json object for all handled exceptions.
On client side I check result object for possible error property before handling valid result.
The handleResponseError method will parse typed Response object and throw observable message. But at least my browser (Chrome 57) seems to automatically log response errors to console. So if subscriber need no specific extra handling for different errors, then the subscriber need no extra action for err object.
Please feedback if there are better ways!
Backend C# code:
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);
}
}
}
Client side Angular 2 code:
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}`);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.