1package otr3 2 3import "fmt" 4 5// ErrorCode represents an error that can happen during OTR processing 6type ErrorCode int 7 8const ( 9 // ErrorCodeEncryptionError means an error occured while encrypting a message 10 ErrorCodeEncryptionError ErrorCode = iota 11 12 // ErrorCodeMessageUnreadable means we received an unreadable encrypted message 13 ErrorCodeMessageUnreadable 14 15 // ErrorCodeMessageMalformed means the message sent is malformed 16 ErrorCodeMessageMalformed 17 18 // ErrorCodeMessageNotInPrivate means we received an encrypted message when not expecting it 19 ErrorCodeMessageNotInPrivate 20) 21 22// ErrorMessageHandler generates error messages for error codes 23type ErrorMessageHandler interface { 24 // HandleErrorMessage should return a string according to the error event. This string will be concatenated to an OTR header to produce an OTR protocol error message 25 HandleErrorMessage(error ErrorCode) []byte 26} 27 28type dynamicErrorMessageHandler struct { 29 eh func(error ErrorCode) []byte 30} 31 32func (d dynamicErrorMessageHandler) HandleErrorMessage(error ErrorCode) []byte { 33 return d.eh(error) 34} 35 36func (c *Conversation) generatePotentialErrorMessage(ec ErrorCode) { 37 if c.errorMessageHandler != nil { 38 msg := c.errorMessageHandler.HandleErrorMessage(ec) 39 c.injectMessage(append(append(errorMarker, ' '), msg...)) 40 } 41} 42 43func (s ErrorCode) String() string { 44 switch s { 45 case ErrorCodeEncryptionError: 46 return "ErrorCodeEncryptionError" 47 case ErrorCodeMessageUnreadable: 48 return "ErrorCodeMessageUnreadable" 49 case ErrorCodeMessageMalformed: 50 return "ErrorCodeMessageMalformed" 51 case ErrorCodeMessageNotInPrivate: 52 return "ErrorCodeMessageNotInPrivate" 53 default: 54 return "ERROR CODE: (THIS SHOULD NEVER HAPPEN)" 55 } 56} 57 58type combinedErrorMessageHandler struct { 59 handlers []ErrorMessageHandler 60} 61 62func (c combinedErrorMessageHandler) HandleErrorMessage(error ErrorCode) []byte { 63 var result []byte 64 for _, h := range c.handlers { 65 if h != nil { 66 result = h.HandleErrorMessage(error) 67 } 68 } 69 return result 70} 71 72// CombineErrorMessageHandlers creates an ErrorMessageHandler that will call all handlers 73// given to this function. It returns the result of the final handler called 74func CombineErrorMessageHandlers(handlers ...ErrorMessageHandler) ErrorMessageHandler { 75 return combinedErrorMessageHandler{handlers} 76} 77 78// DebugErrorMessageHandler is an ErrorMessageHandler that dumps all error message requests to standard error. It returns nil 79type DebugErrorMessageHandler struct{} 80 81// HandleErrorMessage dumps all error messages and returns nil 82func (DebugErrorMessageHandler) HandleErrorMessage(error ErrorCode) []byte { 83 fmt.Fprintf(standardErrorOutput, "%sHandleErrorMessage(%s)\n", debugPrefix, error) 84 return nil 85} 86