github.com/nyan233/littlerpc@v0.4.6-0.20230316182519-0c8d5c48abaf/core/server/server_handle.go (about) 1 package server 2 3 import ( 4 "github.com/nyan233/littlerpc/core/common/msgwriter" 5 "github.com/nyan233/littlerpc/core/common/transport" 6 "github.com/nyan233/littlerpc/core/common/utils/debug" 7 "github.com/nyan233/littlerpc/core/middle/packer" 8 error2 "github.com/nyan233/littlerpc/core/protocol/error" 9 "github.com/nyan233/littlerpc/core/protocol/message" 10 "github.com/nyan233/littlerpc/core/utils/convert" 11 "strconv" 12 ) 13 14 func (s *Server) encodeAndSendMsg(msgOpt *messageOpt, msg *message.Message, beforeErr error2.LErrorDesc, handleErr bool) { 15 if err := s.pManager.Send4S(msgOpt.PCtx, msg, beforeErr); err != nil { 16 s.handleError(msgOpt.Conn, msgOpt.Desc.Writer, msg.GetMsgId(), err) 17 return 18 } 19 if handleErr && beforeErr != nil { 20 s.handleError(msgOpt.Conn, msgOpt.Desc.Writer, msg.GetMsgId(), beforeErr) 21 return 22 } 23 err := msgOpt.Desc.Writer.Write(msgwriter.Argument{ 24 Message: msg, 25 Conn: msgOpt.Conn, 26 Encoder: msgOpt.Packer, 27 Pool: s.pool.TakeBytesPool(), 28 OnDebug: debug.MessageDebug(s.logger, s.config.Load().Debug), 29 EHandle: s.eHandle, 30 }, msgOpt.Header) 31 _ = s.pManager.AfterSend4S(msgOpt.PCtx, msg, err) 32 } 33 34 // NOTE: 这里负责处理Server遇到的所有错误, 它会在遇到严重的错误时关闭连接, 不那么重要的错误则尝试返回给客户端 35 // NOTE: 严重错误 -> UnsafeOption | MessageDecodingFailed | MessageEncodingFailed 36 // NOTE: 轻微错误 -> 除了严重错误都是 37 // Update: LittleRpc现在的错误返回统一使用NoMux类型的消息 38 // writer == nil时从msgwriter选择一个Writer, 默认选择NoMux Write 39 func (s *Server) handleError(conn transport.ConnAdapter, writer msgwriter.Writer, msgId uint64, errNo error2.LErrorDesc) { 40 bytesBuffer := s.pool.TakeBytesPool() 41 cfg := s.config.Load() 42 if writer == nil { 43 writer = cfg.WriterFactory() 44 } 45 // 普通错误打印警告, 严重错误打印error 46 switch errNo.Code() { 47 case error2.UnsafeOption, error2.MessageDecodingFailed, 48 error2.MessageEncodingFailed, error2.ConnectionErr: 49 s.logger.Error("LRPC: trigger must close connection error: %v", errNo) 50 default: 51 s.logger.Warn("LRPC: trigger connection error: %v", errNo) 52 } 53 msg := message.New() 54 msg.SetMsgType(message.Return) 55 msg.SetMsgId(msgId) 56 msg.MetaData.Store(message.ErrorCode, strconv.Itoa(errNo.Code())) 57 msg.MetaData.Store(message.ErrorMessage, errNo.Message()) 58 // 为空则不序列化Mores, 否则会造成空间浪费 59 mores := errNo.Mores() 60 if mores != nil && len(mores) > 0 { 61 bytes, err := errNo.MarshalMores() 62 if err != nil { 63 s.logger.Error("LRPC: handleError marshal error mores failed: %v", err) 64 _ = conn.Close() 65 return 66 } else { 67 msg.MetaData.Store(message.ErrorMore, convert.BytesToString(bytes)) 68 } 69 } 70 err := writer.Write(msgwriter.Argument{ 71 Message: msg, 72 Conn: conn, 73 Encoder: packer.Get("text"), 74 Pool: bytesBuffer, 75 OnDebug: debug.MessageDebug(s.logger, cfg.Debug), 76 OnComplete: nil, //TODO: 将某个合适的插件注入 77 EHandle: s.eHandle, 78 }, message.MagicNumber) 79 if err != nil { 80 s.logger.Error("LRPC: handleError write bytes error: %v", err) 81 } 82 }