commit f1403e4335ed6f975ab98811715b23c205a422c9
parent d56d187be5ac61be68b72c82192bd93a5546b082
Author: Matsuda Kenji <info@mtkn.jp>
Date: Sat, 15 Jul 2023 10:56:06 +0900
implement error
Diffstat:
| M | fcall.go | | | 30 | +++++++++++++++++++++++++++++- |
| M | server.go | | | 33 | ++++++++++++++++++++++++--------- |
2 files changed, 53 insertions(+), 10 deletions(-)
diff --git a/fcall.go b/fcall.go
@@ -189,7 +189,6 @@ func (msg RVersion) String() string {
type TAuth []byte
type RAuth []byte
-type RError []byte
type TAttach []byte
@@ -238,3 +237,31 @@ func (msg RAttach) String() string {
return fmt.Sprintf("Rattach tag %d qid %v",
msg.Tag(), msg.Qid())
}
+
+type RError []byte
+
+func (msg RError) Size() uint32 { return gbit32(msg[0:4]) }
+func (msg RError) SetSize(s uint32) { pbit32(msg[0:4], s) }
+func (msg RError) Type() MsgType { return MsgType(msg[4]) }
+func (msg RError) SetType(t MsgType) { msg[4] = byte(t) }
+func (msg RError) Tag() uint16 { return gbit16(msg[5:7]) }
+func (msg RError) SetTag(t uint16) { pbit16(msg[5:7], t) }
+func (msg RError) conv2M() []byte { return []byte(msg)[:msg.Size()] }
+func (msg RError) EName() error {
+ size := gbit16(msg[7:9])
+ return fmt.Errorf("%s", string(msg[9:9+size]))
+}
+func (msg RError) SetEName(err error) {
+ size := uint32(len(err.Error()))
+ uint16Max := uint32(1 << 16)
+ if size >= uint16Max {
+ panic("error message too large")
+ }
+ pbit16(msg[7:9], uint16(size))
+ for i := 0; i < int(size); i++ {
+ msg[9+i] = err.Error()[i]
+ }
+}
+func (msg RError) String() string {
+ return fmt.Sprintf("Rerror tag %d ename %v", msg.Tag(), msg.EName())
+}
+\ No newline at end of file
diff --git a/server.go b/server.go
@@ -80,6 +80,18 @@ func sVersion(s *Srv, r *Req) {
func rVersion(r *Req, err error) {}
+func rError(r *Req, err error) {
+ size := uint32(4 + 1 + 2 + 2 + len(err.Error()))
+ ofcall := RError(make([]byte, size))
+
+ ofcall.SetSize(size)
+ ofcall.SetType(Rerror)
+ ofcall.SetTag(r.ifcall.Tag())
+ ofcall.SetEName(err)
+
+ r.ofcall = ofcall
+}
+
func Serve(s *Srv) {
for {
r, err := getReq(s)
@@ -89,7 +101,7 @@ func Serve(s *Srv) {
}
switch r.ifcall.Type() {
default:
- log.Print("unknown message type")
+ respond(r, fmt.Errorf("unknown message type: %d", r.ifcall.Type()))
case Tversion:
sVersion(s, r)
}
@@ -97,12 +109,16 @@ func Serve(s *Srv) {
}
func respond(r *Req, err error) {
- switch ofcall := r.ofcall.(type) {
- default:
- // TODO: Respond with Rerror.
- log.Fatalf("unknown message type: %v", ofcall)
- case RVersion:
- rVersion(r, err)
+ if err != nil {
+ rError(r, err)
+ } else {
+ switch ofcall := r.ofcall.(type) {
+ default:
+ // TODO: Respond with Rerror.
+ rError(r, fmt.Errorf("unknown message type: %s", ofcall.Type()))
+ case RVersion:
+ rVersion(r, err)
+ }
}
if chatty9P {
@@ -110,4 +126,4 @@ func respond(r *Req, err error) {
}
r.srv.Write(r.ofcall.conv2M())
-}
-\ No newline at end of file
+}