简体   繁体   English

解释Angular 2中的MVC错误的最佳实践

[英]Best practice for interpreting MVC errors in Angular 2

I have a MVC 5 backend written in C#. 我有一个用C#编写的MVC 5后端。 It serves MVC views written in Razor and also some Angular 2 pages. 它提供了用Razor和Angular 2页面编写的MVC视图。

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: 后端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");
    }
}

Client side Angular 2 code: 客户端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);
}

This is a printscreen of the error object processed by handleError method: 这是由handleError方法处理的错误对象的打印屏幕:

错误对象

This all raises some questions: 这一切都会引起一些问题:

  1. Is it correct to throw custom HttpException from server? 从服务器抛出自定义HttpException是否正确?
  2. Is handleError method correct or maybe too complex? handleError方法正确还是太复杂?
  3. On client side I would like to see the custom error message, but currently it is just found in an enormous "blob" of HTML that is nasty to parse. 在客户端,我希望看到自定义错误消息,但是当前只能在庞大的HTML“ blob”中找到,该HTML很讨厌解析。
  4. Is client side error handling necessary BOTH in get call and subscribe action? 客户端错误处理是否必须在get call和subscription操作中同时进行?

My current suggestion is to let server respond with Json object for all handled exceptions. 我当前的建议是让服务器使用Json对象响应所有已处理的异常。

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. handleResponseError方法将解析键入的Response对象并抛出可观察的消息。 But at least my browser (Chrome 57) seems to automatically log response errors to console. 但是至少我的浏览器(Chrome 57)似乎会自动将响应错误记录到控制台。 So if subscriber need no specific extra handling for different errors, then the subscriber need no extra action for err object. 因此,如果订户不需要针对不同的错误进行特定的额外处理,则订户无需对err对象采取额外的操作。

Please feedback if there are better ways! 如果有更好的方法,请反馈!

Backend C# code: 后端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);
        }
    }
}

Client side Angular 2 code: 客户端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}`);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM