forked from quickfixgo/quickfix
-
Notifications
You must be signed in to change notification settings - Fork 0
/
errors.go
195 lines (161 loc) · 9.01 KB
/
errors.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
// Copyright (c) quickfixengine.org All rights reserved.
//
// This file may be distributed under the terms of the quickfixengine.org
// license as defined by quickfixengine.org and appearing in the file
// LICENSE included in the packaging of this file.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE.
//
// See http://www.quickfixengine.org/LICENSE for licensing information.
//
// Contact [email protected] if any conditions of this licensing
// are not clear to you.
package quickfix
import (
"errors"
"fmt"
)
// ErrDoNotSend is a convenience error to indicate a DoNotSend in ToApp.
var ErrDoNotSend = errors.New("Do Not Send")
// rejectReason enum values.
const (
rejectReasonInvalidTagNumber = 0
rejectReasonRequiredTagMissing = 1
rejectReasonTagNotDefinedForThisMessageType = 2
rejectReasonUnsupportedMessageType = 3
rejectReasonTagSpecifiedWithoutAValue = 4
rejectReasonValueIsIncorrect = 5
rejectReasonConditionallyRequiredFieldMissing = 5
rejectReasonIncorrectDataFormatForValue = 6
rejectReasonCompIDProblem = 9
rejectReasonSendingTimeAccuracyProblem = 10
rejectReasonInvalidMsgType = 11
rejectReasonTagAppearsMoreThanOnce = 13
rejectReasonTagSpecifiedOutOfRequiredOrder = 14
rejectReasonRepeatingGroupFieldsOutOfOrder = 15
rejectReasonIncorrectNumInGroupCountForRepeatingGroup = 16
)
// MessageRejectError is a type of error that can correlate to a message reject.
type MessageRejectError interface {
error
// RejectReason, tag 373 for session rejects, tag 380 for business rejects.
RejectReason() int
BusinessRejectRefID() string
RefTagID() *Tag
IsBusinessReject() bool
}
// RejectLogon indicates the application is rejecting permission to logon. Implements MessageRejectError.
type RejectLogon struct {
Text string
}
func (e RejectLogon) Error() string { return e.Text }
// RefTagID implements MessageRejectError.
func (RejectLogon) RefTagID() *Tag { return nil }
// RejectReason implements MessageRejectError.
func (RejectLogon) RejectReason() int { return 0 }
// BusinessRejectRefID implements MessageRejectError.
func (RejectLogon) BusinessRejectRefID() string { return "" }
// IsBusinessReject implements MessageRejectError.
func (RejectLogon) IsBusinessReject() bool { return false }
type messageRejectError struct {
rejectReason int
text string
businessRejectRefID string
refTagID *Tag
isBusinessReject bool
}
func (e messageRejectError) Error() string { return e.text }
func (e messageRejectError) RefTagID() *Tag { return e.refTagID }
func (e messageRejectError) RejectReason() int { return e.rejectReason }
func (e messageRejectError) BusinessRejectRefID() string { return e.businessRejectRefID }
func (e messageRejectError) IsBusinessReject() bool { return e.isBusinessReject }
// NewMessageRejectError returns a MessageRejectError with the given error message, reject reason, and optional reftagid.
func NewMessageRejectError(err string, rejectReason int, refTagID *Tag) MessageRejectError {
return messageRejectError{text: err, rejectReason: rejectReason, refTagID: refTagID}
}
// NewBusinessMessageRejectError returns a MessageRejectError with the given error mesage, reject reason, and optional reftagid.
// Reject is treated as a business level reject.
func NewBusinessMessageRejectError(err string, rejectReason int, refTagID *Tag) MessageRejectError {
return messageRejectError{text: err, rejectReason: rejectReason, refTagID: refTagID, isBusinessReject: true}
}
// NewBusinessMessageRejectErrorWithRefID returns a MessageRejectError with the given error mesage, reject reason, refID, and optional reftagid.
// Reject is treated as a business level reject.
func NewBusinessMessageRejectErrorWithRefID(err string, rejectReason int, businessRejectRefID string, refTagID *Tag) MessageRejectError {
return messageRejectError{text: err, rejectReason: rejectReason, refTagID: refTagID, businessRejectRefID: businessRejectRefID, isBusinessReject: true}
}
// IncorrectDataFormatForValue returns an error indicating a field that cannot be parsed as the type required.
func IncorrectDataFormatForValue(tag Tag) MessageRejectError {
return NewMessageRejectError("Incorrect data format for value", rejectReasonIncorrectDataFormatForValue, &tag)
}
// repeatingGroupFieldsOutOfOrder returns an error indicating a problem parsing repeating groups fields.
func repeatingGroupFieldsOutOfOrder(tag Tag, reason string) MessageRejectError {
if reason != "" {
reason = fmt.Sprintf("Repeating group fields out of order (%s)", reason)
} else {
reason = "Repeating group fields out of order"
}
return NewMessageRejectError(reason, rejectReasonRepeatingGroupFieldsOutOfOrder, &tag)
}
// ValueIsIncorrect returns an error indicating a field with value that is not valid.
func ValueIsIncorrect(tag Tag) MessageRejectError {
return NewMessageRejectError("Value is incorrect (out of range) for this tag", rejectReasonValueIsIncorrect, &tag)
}
// ValueIsIncorrectWithValue returns an error indicating a field with value that is not valid.
func ValueIsIncorrectWithValue(tag Tag, value string) MessageRejectError {
return NewMessageRejectError(fmt.Sprintf("Value (%s) is incorrect for this tag (%d)", value, tag), rejectReasonValueIsIncorrect, &tag)
}
// ConditionallyRequiredFieldMissing indicates that the requested field could not be found in the FIX message.
func ConditionallyRequiredFieldMissing(tag Tag) MessageRejectError {
return NewBusinessMessageRejectError(fmt.Sprintf("Conditionally Required Field Missing (%d)", tag), rejectReasonConditionallyRequiredFieldMissing, &tag)
}
// valueIsIncorrectNoTag returns an error indicating a field with value that is not valid.
// FIXME: to be compliant with legacy tests, for certain value issues, do not include reftag? (11c_NewSeqNoLess).
func valueIsIncorrectNoTag() MessageRejectError {
return NewMessageRejectError("Value is incorrect (out of range) for this tag", rejectReasonValueIsIncorrect, nil)
}
// InvalidMessageType returns an error to indicate an invalid message type.
func InvalidMessageType() MessageRejectError {
return NewMessageRejectError("Invalid MsgType", rejectReasonInvalidMsgType, nil)
}
// UnsupportedMessageType returns an error to indicate an unhandled message.
func UnsupportedMessageType() MessageRejectError {
return NewBusinessMessageRejectError("Unsupported Message Type", rejectReasonUnsupportedMessageType, nil)
}
// TagNotDefinedForThisMessageType returns an error for an invalid tag appearing in a message.
func TagNotDefinedForThisMessageType(tag Tag) MessageRejectError {
return NewMessageRejectError("Tag not defined for this message type", rejectReasonTagNotDefinedForThisMessageType, &tag)
}
// tagAppearsMoreThanOnce return an error for multiple tags in a message not detected as a repeating group.
func tagAppearsMoreThanOnce(tag Tag) MessageRejectError {
return NewMessageRejectError("Tag appears more than once", rejectReasonTagAppearsMoreThanOnce, &tag)
}
// RequiredTagMissing returns a validation error when a required field cannot be found in a message.
func RequiredTagMissing(tag Tag) MessageRejectError {
return NewMessageRejectError("Required tag missing", rejectReasonRequiredTagMissing, &tag)
}
// incorrectNumInGroupCountForRepeatingGroup returns a validation error when the num in group value for a group does not match actual group size.
func incorrectNumInGroupCountForRepeatingGroup(tag Tag) MessageRejectError {
return NewMessageRejectError("Incorrect NumInGroup count for repeating group", rejectReasonIncorrectNumInGroupCountForRepeatingGroup, &tag)
}
// tagSpecifiedOutOfRequiredOrder returns validation error when the group order does not match the spec.
func tagSpecifiedOutOfRequiredOrder(tag Tag) MessageRejectError {
return NewMessageRejectError("Tag specified out of required order", rejectReasonTagSpecifiedOutOfRequiredOrder, &tag)
}
// TagSpecifiedWithoutAValue returns a validation error for when a field has no value.
func TagSpecifiedWithoutAValue(tag Tag) MessageRejectError {
return NewMessageRejectError("Tag specified without a value", rejectReasonTagSpecifiedWithoutAValue, &tag)
}
// InvalidTagNumber returns a validation error for messages with invalid tags.
func InvalidTagNumber(tag Tag) MessageRejectError {
return NewMessageRejectError("Invalid tag number", rejectReasonInvalidTagNumber, &tag)
}
// compIDProblem creates a reject for msg where msg has invalid comp id values.
func compIDProblem() MessageRejectError {
return NewMessageRejectError("CompID problem", rejectReasonCompIDProblem, nil)
}
// sendingTimeAccuracyProblem creates a reject for a msg with stale or invalid sending time.
func sendingTimeAccuracyProblem() MessageRejectError {
return NewMessageRejectError("SendingTime accuracy problem", rejectReasonSendingTimeAccuracyProblem, nil)
}