3

I'm writing a function which writes a struct of multiple fields to a TCP connection. Is there a way to handle errors in one place like catching exception in Java?

My implementation looks like,

func writeFrame(frame *Frame, conn net.Conn) error { bo := binary.BigEndian if err := binary.Write(conn, bo, frame.ype); err != nil { return err } if err := binary.Write(conn, bo, frame.id); err != nil { return err } if err := binary.Write(conn, bo, frame.seq); err != nil { return err } if err := binary.Write(conn, bo, uint32(len(frame.arg1))); err != nil { return err } if err := binary.Write(conn, bo, uint32(len(frame.arg2))); err != nil { return err } if err := binary.Write(conn, bo, uint32(len(frame.arg3))); err != nil { return err } var csum uint32 if err := binary.Write(conn, bo, csum); err != nil { return err } if _, err := conn.Write(frame.arg1); err != nil { return err } if _, err := conn.Write(frame.arg2); err != nil { return err } if _, err := conn.Write(frame.arg3); err != nil { return err } return nil } 
1

2 Answers 2

2

You can use a bufio.Writer for this. If any error occurs future Write's will simply return the same error and be ignored.

func writeFrame(frame *Frame, conn net.Conn) error { bo := binary.BigEndian w := bufio.NewWriter(conn) binary.Write(w, bo, frame.ype) binary.Write(w, bo, frame.id) binary.Write(w, bo, frame.seq) binary.Write(w, bo, uint32(len(frame.arg1))) binary.Write(w, bo, uint32(len(frame.arg2))) binary.Write(w, bo, uint32(len(frame.arg3))) var csum uint32 binary.Write(w, bo, csum) w.Write(frame.arg1) w.Write(frame.arg2) w.Write(frame.arg3) // Write outstanding data to conn and return an error if any occured return w.Flush() } 
Sign up to request clarification or add additional context in comments.

Comments

2

You could create a simple type that stores a bunch of writes and executes them all at once, bailing as soon as an error is encountered.

type MyWriter struct { W io.Writer O binary.ByteOrder items []interface{} } func (w *MyWriter) AddWrite(value interface{}) { w.items = append(w.items, value) } // PerformWrite executes all writes that have been added via AddWrite. // It aborts as soon as an error is encountered and returns the error. func (w *MyWriter) PerformWrites() error { for _, item := range w.items { if err := binary.Write(w.W, w.O, item); err != nil { return err } } return nil } 

With this in place, your writeFrame function might look something like this:

func Write(conn net.Conn) error { w := MyWriter{W: conn, O: binary.BigEndian} // queue up your writes (frame.type, frame.id, ...) w.AddWrite(int32(1)) w.AddWrite(int32(2)) w.AddWrite(int64(3)) if err := w.PerformWrites(); err != nil { // there was an error return err } return nil } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.