博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
c# api返回后执行代码_API错误代码是历史记录-请尝试执行此操作
阅读量:2522 次
发布时间:2019-05-11

本文共 12560 字,大约阅读时间需要 41 分钟。

c# api返回后执行代码

一个警示故事 (A cautionary tale)

Once upon a time, a young girl observed her mother, who was unwrapping a freshly bought piece of beef for roasting. The mother cut the extremities of the meat out.

曾几何时,一个年轻的女孩观察她的母亲,母亲正在包装新鲜购买的一块牛肉进行烧烤。 母亲把四肢切开。

“Mommy, why do you do that?” the young girl asked.

“妈妈,你为什么要这么做?” 小女孩问。

“It gives a better taste,” the mother replied, as she put the meal in the oven.

母亲把饭放在烤箱里时回答说:“味道更好。”

“How is it so?”

“怎么样?”

“I don’t remember, go ask your grand-mother, she taught me all these kinds of tips and tricks.”

“我不记得了,去问问你的祖母,她教了我所有这些技巧和窍门。”

The child was curious, and ran to the nearby house of her grandmother.

这个孩子很好奇,跑到她祖母附近的房子里。

“Grand-mommy, do you know why cutting the sides of roast beef makes it better?”

“祖母,你知道为什么减少烤牛肉的面使它更好吗?”

“It has to be with the flow of the juice,” the grandmother replied.

奶奶回答说:“必须随果汁的流动而变化。”

“Can’t we just punch holes with a fork instead?”

“我们不能只用叉子打Kong吗?”

“My mother has always prepared them so, and for sure she was a great cook.”

“我的母亲总是为他们做准备,可以肯定的是,她是一位出色的厨师。”

The child was not only curious but also perseverant, and ran to the home where her elder lived. She narrated what her mother and grandmother had told her, and repeated her question.

这个孩子不仅好奇,而且毅力十足,跑到长者居住的家中。 她叙述了母亲和祖母告诉她的内容,并重复了她的问题。

The elder burst in laughter.

老人大笑起来。

“I did always cut the ends of my roast beef, but only because my oven was waaaayyy too small for a whole one.”

“我确实切过烤牛肉的末端,但这只是因为我的烤箱太小了,整个烤箱都太小了。”

This little tale, which exists in, makes an important point about human life. Old habits die hard, even when they haven’t made sense for decades (if ever). And computer science, though evolving at a fast pace, is quite prone to this type of harmful tradition.

这个故事 ,它是人类生活的重要方面。 即使数十年来没有任何意义(即使有),古老的习惯也很难消亡。 尽管计算机科学发展Swift,但很容易受到这种有害传统的影响。

错误处理 (Error handling)

Take error handling, for example. We are deeply used to HTTP status codes, to small unix “errnos”, to lengthy windows error codes… and our APIs are filled with custom numbers, indicating problems with inputs, or with SQL operational errors, or with access permissions…

以错误处理为例。 我们非常熟悉HTTP状态代码,小型unix“ errnos”,冗长的Windows错误代码……并且我们的API充满了自定义数字,表示输入问题,SQL操作错误或访问权限……

The first, low level, programming languages — including C and Fortran — had very rudimentary data types. That’s why they handled errors as mere integers, that they could compare, switch-case, lookup as array indices, and transmit painlessly. And that’s why they ended up using 0 (boolean False) to indicate all successes, and non-zero integers (boolean True) to indicate errors — something not deeply intuitive to ordinary mortals.

第一种底层编程语言(包括C和Fortran)具有非常基本的数据类型。 这就是为什么他们将错误仅作为整数来处理,以便可以进行比较,切换大小写,查找为数组索引并进行轻松传输的原因。 这就是为什么它们最终使用0(布尔False)来表示所有成功,而使用非零整数(布尔True)来表示错误的原因-对于普通凡人来说,这是不那么直观的。

But what do we expect from errors in our everyday modern, high level languages ? That they be:

但是,我们对日常的现代高级语言中的错误有何期待? 他们是:

  • explicit, so we know what they mean without asking the whole web everytime

    明确的 ,因此我们无需每次询问整个网络就知道它们的含义。

  • deeply hierarchical, so that we can refine error cases without breaking current software, and fallback to generic treatments when too specific errors are encountered

    深入的层次结构 ,因此我们可以在不破坏当前软件的情况下优化错误情况,并在遇到过于具体的错误时退回通用处理

  • contextualized, so that additional data may accompany the error, and detail what exactly went wrong and why

    上下文相关 ,以便其他数据可能伴随错误,并详细说明错误的原因和原因

This is the way exceptions are implemented in many modern languages. There are hierarchies of classes with (hopefully) clear meanings. Each has different instance attributes in different branches in these hierarchies, for example filenames, field names, and origin OS errors. And those instances drag with them tons of information, including tracebacks and their per-frame local variables.

这是在许多现代语言中实现异常的方式。 存在具有(希望)具有清晰含义的类层次结构。 每个人在这些层次结构的不同分支中具有不同的实例属性,例如文件名,字段名称和原始OS错误。 这些实例会拖累大量信息,包括回溯及其每帧局部变量。

But when it’s time for the error to cross the boundaries of this specific process, of this specific language? Error codes are amongst the worst supports for this.

但是何时应该让错误越过这种特定过程,这种特定语言的界限呢? 错误代码是对此的最差支持。

What does “Error 0x29273363833” mean? You have no idea. You can’t subdivide this error into more precise cases. If you want more context information, you’ll have to fetch it somewhere else.

“错误0x29273363833”是什么意思? 你不知道。 您无法将此错误细分为更精确的情况。 如果需要更多上下文信息,则必须在其他地方获取它。

And you have little clue what the closest parent error code could be. True, some systems advocate rudimentary fallback behaviours — for example if you encounter an unknown HTTP 478 error, you’re supposed to handle it as an HTTP 400. But it is still a bit too coarse-grained for lots of cases, and once you have used all the numbers of an error class, you’re out-of-luck.

而且您几乎不知道最接近的父错误代码是什么。 的确,某些系统提倡基本的回退行为-例如,如果遇到未知的HTTP 478错误,则应将其作为HTTP 400进行处理。但是对于许多情况而言,它仍然有点过于粗略,一旦您已经使用了错误类别的所有数字,那么您真不走运。

那我有什么建议呢? (So what do I propose?)

Just map exception types to their closest JSON-compatible representations. Which happen to be… sequences of identifiers.

只需将异常类型映射到它们最接近的JSON兼容表示即可。 碰巧是……标识符序列。

Ladies and gentlemen, I present to you, a bunch of status slugs:

女士们,先生们,我向您介绍一些身份sl

  • [“Exception”, “LookupError”, “KeyError”]

    [“异常”,“ LookupError”,“ KeyError”]
  • “error|functional|invalid_input|missing_value”

    “错误|功能|无效输入|缺失值”
  • “error|technical|connectivity|mysql.database_unreachable”

    “错误|技术|连接性| mysql.database_unreachable”
  • [“success”]

    [“成功”]
  • [“success”, “instance_found_in_cache”]

    [“成功”,“ instance_found_in_cache”]

As you can see, whether we use lists or strings doesn’t matter much ; even the term “slug” must not be taken too rigidly, having underscores or capital letters in them is harmless.

如您所见,我们使用列表还是字符串都没关系; 即使“子弹”一词也不能太刻板,因为其中带有下划线或大写字母是无害的。

The important take-away messages are that these slugs are:

重要的外卖 消息是这些弹头是:

  • quite explicit

    相当明确
  • quite easy to map to language-specific exceptions

    映射到特定于语言的异常非常容易
  • quite easy to match in the error handling dispatcher.

    在错误处理分派器中非常容易匹配。

Dots should be reserved to qualify, and thus differentiate, same-name exceptions provided by different packages. An example here is “cuteforms.Invalid” vs “validator.Invalid”.

应该保留点以限定并区分不同程序包提供的同名异常。 这里的一个示例是“ cuteforms.Invalid”与“ validator.Invalid”。

The cherry on the cake is that status slugs may be used to distinguish success cases too, like the “HTTP 2XX” family advocated it for the web.

可喜的是,状态标记也可以用来区分成功案例,例如“ HTTP 2XX”家族在网络上倡导它。

So here is the first point I wanted to make: use status slugs to announce operation results.

因此,这是我要说明的第一点: 使用状态块来宣布操作结果

Error handling is at the very core of software robustness and a pleasant user experience, so it deserves more than assembly-level data types. Let’s just stop using poor error dispatching based on integers, on single slugs, or — worst of all — on booleans.

错误处理是软件健壮性和令人愉悦的用户体验的核心,因此,它比程序集级数据类型更有价值 。 让我们停止使用基于整数,单个子块或布尔值(最糟糕的是)的差错错误分配。

The second point I wanted to make about error handling is: be ambitious.

关于错误处理,我想说的第二点是: 有野心

Lots of protocols define castrated error structures — “if it’s enough for me, it’s enough for others”. And developers end up adding their own error handling system. Sometimes SUCCESS responses of initial protocol are stuffed with their own error structures, when ERROR responses leave no room for customization (looking at you, XML-RPC).

许多协议定义了cast割的错误结构-“如果对我足够,对其他人也足够”。 开发人员最终添加了自己的错误处理系统。 有时,初始协议的SUCCESS响应会填充自己的错误结构,而ERROR响应则没有自定义的余地(看着您,XML-RPC)。

So if you end up, one day, having to specify your own error format — which is always a pity, but sometimes unavoidable — think big.

因此,如果最终有一天,您必须指定自己的错误格式(这总是很遗憾,但有时是不可避免的),请考虑大事

What do we expect from a response format?

我们对响应格式有什么期望?

  • For sure we need status slugs, to see precisely which kind of success or error occurred.

    当然,我们需要状态专家,以准确查看发生了哪种成功或错误。
  • We may also need translated messages for UI display.

    我们可能还需要翻译后的消息才能显示UI。
  • Most probably we need untranslated messages too, as they are much more convenient to seek in source codes, or to translate frontend-side.

    我们很可能也需要未翻译的消息,因为它们更容易在源代码中查找或翻译前端。
  • We need room for status-specific trees of data, so that all relevant information may be provided in a machine-processable way.

    我们需要空间来存储特定于状态的数据树,以便可以以机器可处理的方式提供所有相关信息。
  • We probably also need support for multiple — or rather recursive — data structures, like when several fields of a web form each have their own reason to be rejected.

    我们可能还需要支持多个(或更确切地说是递归)数据结构,例如当Web表单的多个字段各自都有其自己的理由被拒绝时。
  • We might have to convey partial successes, for example when not all user account data could be retrieved from directories. We might have to convey and partial failures, for example when an authoritative answer could not be fetched, but some cached data is returned just in case it helps you.

    例如,当并非所有用户帐户数据都可以从目录中检索时,我们可能必须传达部分成功。 我们可能必须传达一些和部分的失败,例如,当无法获取权威性答案时,会返回一些缓存的数据,以防万一它对您有所帮助。

Here is an example of an (almost) one-size-fits-all StatusPack structure:

这是一个(几乎)千篇一律的StatusPack结构的示例:

{

{

status_slugs : list of slugs for success/error dispatching, mandatory field

status_slugs:成功/错误调度的段列表,必填字段

data: data tree with contextual information (results, invalid input fields...)

数据:具有上下文信息的数据树(结果,无效的输入字段...)

traceback : for dev mode only, might include frames with local variables

traceback:仅适用于开发模式,可能包含带有局部变量的框架

nested_statuses: optional list of StatusPack structures

nested_statuses:StatusPack结构的可选列表

message_translated: displayable string

message_translated:可显示的字符串

message_untranslated: string or [string template, parameters] pair

message_untranslated:字符串或[字符串模板,参数]对

This structure should cover the use cases mentioned above, thanks to the malleability provided by the “nested_statuses” field.

由于“ nested_statuses”字段提供的可扩展性,该结构应涵盖上述用例。

If you deal with microservices, chaining these status packs, and displaying them properly user-side — especially the traceback — might save you days of logs investigations.

如果您处理微服务 ,则将这些状态包链接起来,并在用户端( 尤其是回溯)正确显示它们,可能会节省几天的日志调查时间。

And if you want to obfuscate your errors, then fine. But there is no need to specify error codes yourself. Just create hashes of your “status_slugs” and automatically generate the whole listing of available errors by introspecting your codebase.

如果您想掩盖错误,那很好。 但是无需自己指定错误代码。 只需创建“ status_slugs”的哈希值 ,然后通过内省代码库自动生成可用错误的完整清单。

The last point I am emphasizing is: be kind to API consumers.

我要强调的最后一点是: 对API使用者要友善。

Ensure that your consumers know when an error occurs. Ensure that your consumers also know what to do, especially programmatically, in this case.

确保您的消费者知道何时发生错误。 在这种情况下,请确保您的消费者也知道该怎么做,尤其是通过编程。

  • Silent errors are Hell’s antechamber. Deleting a non-existing account must return an error. But provide a gentle “strict=False” parameter to such operations, so that users may issue unimportant calls without embarrassing themselves with errors.

    无声的错误是地狱的前厅。 删除不存在的帐户必须返回错误。 但是请为此类操作提供一个温和的“ strict = False”参数,以便用户可以发出不重要的呼叫而不会因错误而尴尬。

  • Having a “ValueError” on a form field that users submitted (input error), or on a variable which they know nothing about (server error), are totally different cases. These should end up as different status slugs. When your API acts as a relay between users and other APIs, this analysis might be very hard to achieve, especially if remote APIs have poor error reporting. But try, anyway.

    在用户提交的表单字段上出现“ ValueError”(输入错误),或者在用户不知道的变量上出现“ ValueError”(服务器错误)是完全不同的情况。 这些应该以不同的状态段结束。 当您的API充当用户和其他API之间的中继时,这种分析可能很难实现,尤其是在远程API的错误报告不佳的情况下。 但是无论如何,请尝试。
  • Be clear, in your documentation, about the meaning of error classes, and what actions are expected from consumers. Typically, technical errors mean “if you retry later, it might work.” On the other hand, functional errors mean “your workflows or inputs are wrong, blindly retrying won’t help.” Your hierarchy of status slugs might need to be fine-tuned, with love and attention, over several years.

    在您的文档中,请明确有关错误类的含义以及期望使用者采取的措施。 通常,技术错误表示“如果稍后重试,它可能会起作用”。 另一方面,功能错误表示“您的工作流程或输入错误,盲目重试将无济于事。” 几年来,可能需要通过爱心和关注来微调您的状态状态等级。

These two ideas — status slugs and StatusPack structures are certainly not the epitome of error handling, but they represent a sure step forward in terms of precision and evolvability.

这两个想法- 状态段和StatusPack结构 - 绝对不是错误处理的缩影,但它们在准确性和可扩展性方面代表了肯定的进步。

I’d like to hear the other error fields, or other handling strategies, that API developers around here might have come up with. Please share your innovations and hard-earned lessons!

我想听听附近的API开发人员可能想出的其他错误字段或其他处理策略。 请分享您的创新和来之不易的教训!

Edited on 2018/09/07: Fix typos, and precise the idea behind the “slug” term.

于2018年9月7日编辑:修正了拼写错误,并完善了“弹头”一词背后的想法。

Edited on 2019/06/22: Precise the StatusPack "data" field

于2019/06/22编辑:精确的StatusPack“数据”字段

翻译自:

c# api返回后执行代码

转载地址:http://uckzd.baihongyu.com/

你可能感兴趣的文章
3天CSS总结
查看>>
一周复习总结(一)第二周
查看>>
similarity 字符串编辑距离相似度匹配
查看>>
linux中什么是shell?
查看>>
谈谈MySql数据库锁
查看>>
Mac上搭建rtmp流媒体服务器(结合FFmpeg的使用)
查看>>
mybatis06--动态sql
查看>>
C# WinForm开发系列 - Controls
查看>>
Thrust快速入门教程(二)——Vector的使用
查看>>
Java的概念
查看>>
opencv图像线性混合&imread()
查看>>
C++计算毫秒
查看>>
Spring IOC(转载)
查看>>
Java实现归并排序
查看>>
JQuery 前台传值到后台并调用后台方法
查看>>
Appium+Python3+ Android入门
查看>>
linux $ 类型变量 及Makefile 中 $ 类型变量的含义
查看>>
MyBatis插件及示例----打印每条SQL语句及其执行时间
查看>>
2.2
查看>>
[JS]事件捕获和冒泡
查看>>