调试并避免周期性的 REBOL2 错误,try[] 没有(?)捕获?

Debug and avoid periodic REBOL2 error, that try[] does not(?) catch?

在使用 Rebol/Core (278-3-1) 制作一种服务于静态文本的网络服务器时显然无法捕获错误,包含重定向 link 到一个新的服务地点。

错误的具体位置似乎是 Carl Sassenrath 自己在 2006 年编写的示例代码中,所以我有点困惑,这么多年了,居然还有一个未检测到的错误。

我同时拥有三个这样的脚本 运行,监控三个单独的端口。从本质上讲,该脚本按其应有的方式工作……当同时使用多个浏览器(在所有并行脚本上)重复访问时,它似乎非常稳定……但是一个接一个地失败了。有时在 2 分钟后,有时在 20 分钟后 - 添加打印语句后有时甚至在 60 分钟后 - 但最终它们会像这样失败:

** Script Error: Out of range or past end
** Where: forever
** Near: not empty? request: first http-port

我已经尝试将程序循环的几乎每个部分包装在 try[][异常] 中,但错误仍然存​​在。不幸的是,每年这个时候我的搜索功能似乎很弱,因为我没有找到任何可以解释问题的东西。

该代码是 Carl Sassenrath 的 Tiny Web Server 的精简版,稍作修改以绑定到特定 IP,并发出 HTML 而不是加载文件:

REBOL [title: "TestMovedServer"]
AppName: "Test"
NewSite: "http://test.myserver.org"

listen-port: open/lines tcp://:81   browse http://10.100.44.6?
buffer: make string! 1024  ; will auto-expand if needed

forever [
    http-port: first wait listen-port
    clear buffer

    while [not empty? request: first http-port][
        print request
        repend buffer [request newline]
        print "----------"
    ]
    repend buffer ["Address: " http-port/host newline] 
    print buffer
    Location: ""
    mime: "text/html"
    parse buffer ["get" ["http" | "/ " | copy Location to " "]]

    data: rejoin [{
        <HTML><HEAD><TITLE>Site Relocated</TITLE></HEAD>
        <BODY><CENTER><BR><BR><BR><BR><BR><BR>
        <H1>} AppName { have moved to <A HREF="} NewSite {">} NewSite {</A></H1>
        <BR><BR><BR>Please update the link you came from.
        <BR><BR><BR><BR><BR><A HREF="} NewSite Location {">(Continue directly to the requested page)</A>
        </CENTER></BODY></HTML>
    }]  
    insert data rejoin ["HTTP/1.0 200 OK^/Content-type: " mime "^/^/"]
    write-io http-port data length? data
    close http-port
    print "============"
]

我很期待看到你们从中得到什么!

尝试从已关闭的连接中读取时出现错误。这似乎有效。

n: 0
forever [
   http-port: first wait listen-port
   clear buffer
   if attempt [all [request: first http-port  not empty? request]] [
      until [
        print request
        repend buffer [request newline]
        print "----------"
        any [not request: first http-port empty? request]
      ]
      repend buffer ["Address: " http-port/host newline] 
      print buffer
      Location: ""
      mime: "text/html"
      parse buffer ["get" ["http" | "/ " | copy Location to " "]]

      data: rejoin [{
        <HTML><HEAD><TITLE>Site Relocated</TITLE></HEAD>
        <BODY><CENTER><BR><BR><BR><BR><BR><BR>
        <H1>} AppName n: n + 1 { has moved to <A HREF="} NewSite {">} NewSite {</A></H1>
        <BR><BR><BR>Please update the link you came from.
        <BR><BR><BR><BR><BR><A HREF="} NewSite Location {">(Continue directly to the requested page)</A>
        </CENTER></BODY></HTML>
      }]  
      insert data rejoin ["HTTP/1.0 200 OK^/Content-type: " mime "^/^/"]
      write-io http-port data length? data
  ]
  attempt [close http-port]
  print "============"
]

让我们看看文档是否为空? 摘要:

Returns 如果系列位于其尾部则为 TRUE。 用法:

空?系列 参数:

series - 系列参数。 (必须是:串口位集)

这么空?需要系列、端口或位集或字符串参数。只要与端口的连接处于打开状态,您的变量 (request) 就会获取其中任何一个。空的?之后可以判断它是否在变量的尾部。 当连接为 closed/interrupted 时,您的变量什么也没收到,但连接到端口时出现访问错误。错误没有尾巴。空的?感到困惑并因错误而崩溃。

sqlab已经替换为空?尝试

if attempt [all [request: first http-port  not empty? request]]

ATTEMPT 函数是以下常见情况的快捷方式:

error? try [block]

with all他和none一样在防错。 如果没有发生错误,ATTEMPT returns 块的结果。如果确实发生错误,则返回 NONE。 还有直到

any [not request: first http-port empty? request]

两者都防着

因此他的代码有效。