Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exceptions #12

Open
1ber opened this issue Apr 10, 2018 · 6 comments
Open

Exceptions #12

1ber opened this issue Apr 10, 2018 · 6 comments
Assignees
Milestone

Comments

@1ber
Copy link

1ber commented Apr 10, 2018

There is some reason to return null instead of raising exceptions in parser.get_message ?

@da4089
Copy link
Owner

da4089 commented Apr 10, 2018

When receiving messages via a socket connection, it's common to receive partial messages when under load. As these partial messages are appended to the reassembly buffer (using append_buffer, you can sometimes get no new FIX message from the appended bytes (and sometimes get multiple FIX messages).

So the recommended structure is to call get_message until it returns None.

I thought this was better than returning, eg. StopIteration, which would make the more usual case where you get one FIX message for each append_buffer kinda ugly.

That said, I'm playing with extensions to get_message that will do more (and optionally less) validation of the messages when parsing, and it would be possible to add an option to have it raise something rather than return None.

What's your use-case? Why is an exception the best solution for you? What exception would you expect?

@1ber
Copy link
Author

1ber commented Apr 11, 2018

I'm not in a real case scenario, i have already work with a big project with FIX, but in java.
I'm not an expert in python too, and i'm only playing with your lib. For me the advantage of exceptions would be a better description of the problem.
Don't get me wrong, i can be totally wrong, it's just that when i was playing with it, exceptions appears to me as a good idea in this scenario.
There is a lot of other things that can go wrong, apart from the message not being fully received. If everything return null there is no way to check what's wrong.
I pasted some sugestions bellow, but the best aprroach would be (i think) to have an Exception hierarchy that will give better clues of what is going wrong. Some pseudo-code/sugestions below:

` if len(self.pairs) == 0:
raise EmptySelfPairsException ( 'Empty pairs')

    # Check first pair is FIX BeginString.
    while self.pairs and self.pairs[0][0] != 8:
        # Discard pairs until we find the beginning of a message.
        self.pairs.pop(0)

    if len(self.pairs) == 0:
        raise EmptySelfPairsException ( 'Empty pairs')

    # Look for checksum.
    index = 0
    while index < len(self.pairs) and self.pairs[index][0] != 10:
        index += 1

    if index == len(self.pairs):
        raise ZeroIndexPairsException ( 'index==self.pairs')`

@da4089
Copy link
Owner

da4089 commented Apr 11, 2018

There is an interesting slippery slope here: the goal of a simple FIX library is to avoid some of the complexity of using, eg. QuickFIX. Once you start down the route of checking for tag 8 at the start, you end up then wanting to check tag 9 is next, and then tag 35, and then ... pretty soon you end up validating messages against a full spec/schema.

That said, the only way I currently check for message boundaries is tag 10, so ... there's at least a toe on that slope already.

I will think some more about this.

In the meantime, you should know that a returned None is not an error, it just means that no completed message has been found in the bytes accumulated so far. And you should normally call get_message repeatedly until it returns None when attempting to drain the accumulated buffer.

@1ber
Copy link
Author

1ber commented Apr 11, 2018

Hum, i understand you and recognize the merits of your view.
Should i close this issue?
Or you?
Tks

@da4089
Copy link
Owner

da4089 commented Apr 11, 2018

If you don't mind, I'd like to leave this open while I think some more. I'll update it once I've got a tentative plan, and see what you think.

@da4089 da4089 added this to the Release v1.1 milestone Apr 17, 2018
@da4089
Copy link
Owner

da4089 commented Apr 18, 2018

Ok, here's my plan:

  • I will add a bunch of behavioural settings to the parser
  • These can be enabled or disabled either by calling FixParser.set_foo or passing foo=<bool> to the parser constructor
  • One of these will be set_exceptions() (also, exceptions=True)

This setting will enable more detailed error detection and reporting, using a suitable set of Exception sub-classes defined for the various parsing errors.

I expect I'll have this done within a week or so.

@da4089 da4089 self-assigned this Apr 18, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants