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