实现各种错误处理和资源管理。
编程中重要的一点是,即使出现错误,也要处理错误并关闭资源。
这个练习要求你处理各种错误。 因为错误处理相当依赖于具体的编程语言,你需要参考你所在语言轨道的测试来了解具体要求。
你正在构建一个小巧的 Web 服务器,用来查询一个更小巧的用户数据库。听起来很简单,但在现实世界中,很多事情都可能(而且经常会)出错:
"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))。
好,我们开始吧!你需要做的是:
get_user,从users“数据库”(实际上只是一个Dict)中返回请求的用户。确保在找不到用户时,函数返回Err(UserNotFound(user_id)),而不是Err(KeyNotFound)。parse_user_id,把 URL 的路径(例如"/users/123")转换成正整数用户 ID(123)。如果出错,返回Err(InvalidUserId(user_id_str))。getPage:
"https://example.com/",返回Ok("Home page")
"https://example.com/users/",返回Ok("Users page")
"https://example.com/users/<user_id>",解析用户 ID,加载该 ID 对应的用户,并返回Ok("<user name>'s page")
"https://",返回Err(InsecureConnection(url))
"example.com",返回Err(InvalidDomain(url))
/、/users/或/users/<user id>,返回Err(PageNotFound(path))
Err(InvalidUserId(user_id_str))
Err(UserNotFound(user_id))
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 中的错误是对机器友好的,实现起来会非常容易。