轨道
/
Roc
Roc
/
练习
/
错误处理
错误处理

错误处理

中等

说明

实现各种错误处理和资源管理。

编程中重要的一点是,即使出现错误,也要处理错误并关闭资源。

这个练习要求你处理各种错误。 因为错误处理相当依赖于具体的编程语言,你需要参考你所在语言轨道的测试来了解具体要求。

实现

你正在构建一个小巧的 Web 服务器,用来查询一个更小巧的用户数据库。听起来很简单,但在现实世界中,很多事情都可能(而且经常会)出错:

  • 连接可能不安全:URL 必须以"https://"开头
  • 域名可能无效:在本练习中,它应该是"example.com"
  • 页面可能找不到:只允许"https://example.com/"、"https://example.com/users/"和"https://example.com/users/<user_id>"
  • user_id可能不是正整数
  • 数据库里可能不存在这个user_id对应的用户

出错时,给最终用户一条友好、有用的错误信息很重要,这样他们才能解决问题。为此,你需要确保代码能把有用的错误从检测到错误的位置传递到生成错误信息的位置。

幸运的是,Roc 允许你在Err标签里携带载荷(也就是数据)。直接携带一条错误信息(例如Err("User #42 was not found"))很诱人,在某些简单情况下这样也许没问题,但它有几个局限:

  • 检测错误的函数内部可能没有足够的上下文,无法生成足够有用的错误信息。
    • 例如,Str.to_u64函数可以用来解析各种整数:天数、秒数、用户 ID 等等。如果错误信息只是说Could not convert string "0.5" to a positive integer,用户可能没有足够的上下文来解决问题。
  • 在很多情况下,你的错误处理代码可能需要区别对待不同的错误。但是,如果错误只携带字符串载荷,你的错误处理代码就必须解析那个字符串才能知道出了什么问题:这既低效,又很容易在错误信息被改动时出问题。
  • 如果你的网站支持多种语言,你就需要把错误信息翻译成用户的语言。如果错误载荷是对机器友好的数据,而不是一个英文字符串,这件事就会容易得多。

所以在本练习中,你的错误会改为携带一个有意义的标签,以及它自带的有用载荷。例如,如果找不到用户,错误会像这样:Err(UserNotFound(42))。

好,我们开始吧!你需要做的是:

  1. 实现get_user,从users“数据库”(实际上只是一个Dict)中返回请求的用户。确保在找不到用户时,函数返回Err(UserNotFound(user_id)),而不是Err(KeyNotFound)。
  2. 实现parse_user_id,把 URL 的路径(例如"/users/123")转换成正整数用户 ID(123)。如果出错,返回Err(InvalidUserId(user_id_str))。
  3. 实现getPage:
    • 如果 URL 是"https://example.com/",返回Ok("Home page")
    • 如果 URL 是"https://example.com/users/",返回Ok("Users page")
    • 如果 URL 是"https://example.com/users/<user_id>",解析用户 ID,加载该 ID 对应的用户,并返回Ok("<user name>'s page")
    • 如果 URL 前缀不是"https://",返回Err(InsecureConnection(url))
    • 如果 URL 域名不是"example.com",返回Err(InvalidDomain(url))
    • 如果路径不是/、/users/或/users/<user id>,返回Err(PageNotFound(path))
    • 如果用户 ID 不是正整数,返回Err(InvalidUserId(user_id_str))
    • 如果用户不存在,返回Err(UserNotFound(user_id))
  4. 实现error_essage,把前面那些错误转换成翻译后的错误信息。这个函数至少应该处理英语,不过也鼓励你尝试处理另一种语言。英语错误信息应该像这样:
  • "Insecure connection (non HTTPS): http://example.com/users/789"
  • "Invalid domain name: https://google.com/wrong"
  • "Page not found: /oops"
  • "User ID is not a positive integer: abc"
  • "User #42 was not found"

注意:当用户使用 HTTP 而不是 HTTPS 时,你的 Web 服务器也可以把他们的浏览器重定向到 HTTPS,而不是给用户显示错误信息,这样用户甚至不会察觉到错误。既然 Roc 中的错误是对机器友好的,实现起来会非常容易。

通过 GitHub 编辑 链接将在新窗口或新标签页中打开
Roc Exercism

准备好开始 错误处理 了吗?

注册 Exercism,借助 126 个练习 和真人导师指导,学习并掌握 Roc,全部免费。