Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #91953 > unrolled thread
| Started by | Cecil Westerhof <Cecil@decebal.nl> |
|---|---|
| First post | 2015-06-03 14:27 +0200 |
| Last post | 2015-06-04 07:13 +0200 |
| Articles | 9 — 5 participants |
Back to article view | Back to comp.lang.python
Retrying to send message Cecil Westerhof <Cecil@decebal.nl> - 2015-06-03 14:27 +0200
Re: Retrying to send message Chris Angelico <rosuav@gmail.com> - 2015-06-03 23:29 +1000
Re: Retrying to send message Cecil Westerhof <Cecil@decebal.nl> - 2015-06-03 18:15 +0200
Re: Retrying to send message MRAB <python@mrabarnett.plus.com> - 2015-06-03 19:12 +0100
Re: Retrying to send message Ethan Furman <ethan@stoneleaf.us> - 2015-06-03 11:28 -0700
Re: Retrying to send message Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-06-03 21:37 +0100
Re: Retrying to send message Chris Angelico <rosuav@gmail.com> - 2015-06-04 08:00 +1000
Re: Retrying to send message Ethan Furman <ethan@stoneleaf.us> - 2015-06-03 16:15 -0700
Re: Retrying to send message Cecil Westerhof <Cecil@decebal.nl> - 2015-06-04 07:13 +0200
| From | Cecil Westerhof <Cecil@decebal.nl> |
|---|---|
| Date | 2015-06-03 14:27 +0200 |
| Subject | Retrying to send message |
| Message-ID | <87egltht87.fsf@Equus.decebal.nl> |
I am using libturpial to post messages on Twitter. Sometimes I get a
libturpial.exceptions.ServiceOverCapacity.
It is a good idea to try it again then. For this I wrote the following
function:
def send_message(account_id, message, max_tries, terminate_program):
error_msg = 'Something went wrong with: ' + message
not_send = True
tries = 0
while not_send:
try:
Core().update_status(account_id, message)
except libturpial.exceptions.ServiceOverCapacity:
tries += 1
print('Tried to send it {0} times'.format(tries))
if tries >= max_tries:
terminate_program(error_msg)
time.sleep(60)
except:
terminate_program(error_msg)
else:
not_send = False
Is this a reasonable way to implement this, or is another way better?
Well, maybe the timeout should be a parameter also. ;-)
Also the documentation of time.sleep says:
The actual suspension time may be less than that requested because
any caught signal will terminate the sleep() following execution
of that signal’s catching routine.
My program does not much else as sending the message. So I think it is
not necessary to cover for this possibility. Are I assuming to much?
--
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof
[toc] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-06-03 23:29 +1000 |
| Message-ID | <mailman.108.1433338144.13271.python-list@python.org> |
| In reply to | #91953 |
On Wed, Jun 3, 2015 at 10:27 PM, Cecil Westerhof <Cecil@decebal.nl> wrote:
> def send_message(account_id, message, max_tries, terminate_program):
> error_msg = 'Something went wrong with: ' + message
> not_send = True
> tries = 0
> while not_send:
> try:
> Core().update_status(account_id, message)
> except libturpial.exceptions.ServiceOverCapacity:
> tries += 1
> print('Tried to send it {0} times'.format(tries))
> if tries >= max_tries:
> terminate_program(error_msg)
> time.sleep(60)
> except:
> terminate_program(error_msg)
> else:
> not_send = False
>
> Is this a reasonable way to implement this, or is another way better?
> Well, maybe the timeout should be a parameter also. ;-)
I'd skip the not_send flag and do the logic thusly:
while True:
try:
update_status as above
break
except ServiceOverCapacity:
as above
And I'd also skip the bare except clause. If you get any sort of
exception, whether it's a bug, a failure from libturpial, a network
error, or anything else, your code will just terminate with a bland
and useless message. Much better to simply let the exception bubble
up.
> Also the documentation of time.sleep says:
> The actual suspension time may be less than that requested because
> any caught signal will terminate the sleep() following execution
> of that signal’s catching routine.
>
> My program does not much else as sending the message. So I think it is
> not necessary to cover for this possibility. Are I assuming to much?
I wouldn't worry too much about a signal cutting your sleep short; it
doesn't look to me as if "exactly sixty seconds" is all that crucial
here. If your program sleeps for 42.645 seconds and then gets woken up
by a signal, and you retry a bit sooner than you otherwise would have,
is it going to break anything? If not, just ignore that possibility.
ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Cecil Westerhof <Cecil@decebal.nl> |
|---|---|
| Date | 2015-06-03 18:15 +0200 |
| Message-ID | <876174ix9n.fsf@Equus.decebal.nl> |
| In reply to | #91962 |
Op Wednesday 3 Jun 2015 15:29 CEST schreef Chris Angelico:
> On Wed, Jun 3, 2015 at 10:27 PM, Cecil Westerhof <Cecil@decebal.nl> wrote:
>> def send_message(account_id, message, max_tries,
>> terminate_program): error_msg = 'Something went wrong with: ' +
>> message not_send = True tries = 0 while not_send: try:
>> Core().update_status(account_id, message) except
>> libturpial.exceptions.ServiceOverCapacity: tries += 1 print('Tried
>> to send it {0} times'.format(tries)) if tries >= max_tries:
>> terminate_program(error_msg) time.sleep(60) except:
>> terminate_program(error_msg) else: not_send = False
>>
>> Is this a reasonable way to implement this, or is another way
>> better? Well, maybe the timeout should be a parameter also. ;-)
>
> I'd skip the not_send flag and do the logic thusly:
>
> while True:
> try:
> update_status as above
> break
> except ServiceOverCapacity:
> as above
Yes that is much better. I now made it:
def send_message(account_id, message, max_tries, give_error, wait_time = 60):
error_msg = 'Something went wrong with: ' + message
tries = 0
while True:
try:
Core().update_status(account_id, message)
break
except libturpial.exceptions.ServiceOverCapacity:
tries += 1
print('Tried to send it {0} times'.format(tries))
if tries >= max_tries:
give_error(error_msg)
return
time.sleep(wait_time)
except:
give_error(error_msg)
return
> And I'd also skip the bare except clause. If you get any sort of
> exception, whether it's a bug, a failure from libturpial, a network
> error, or anything else, your code will just terminate with a bland
> and useless message. Much better to simply let the exception bubble
> up.
I kept the except. I like to see the message that went wrong. ;-)
Also, in my case give_error terminates the program, but it never hurts
to make functionality generic, so I added return statements. Not
break, because on error you should leave the function. Break would in
this instance do the same, but I find this neater.
>> Also the documentation of time.sleep says:
>> The actual suspension time may be less than that requested because
>> any caught signal will terminate the sleep() following execution
>> of that signal’s catching routine.
>>
>> My program does not much else as sending the message. So I think it
>> is not necessary to cover for this possibility. Are I assuming to
>> much?
>
> I wouldn't worry too much about a signal cutting your sleep short;
> it doesn't look to me as if "exactly sixty seconds" is all that
> crucial here. If your program sleeps for 42.645 seconds and then
> gets woken up by a signal, and you retry a bit sooner than you
> otherwise would have, is it going to break anything? If not, just
> ignore that possibility.
Correct, so I did not assume to much. :-D
Usually I check parameters. But I understood that is not the Python
way. For example a wait_time of 1, or negative is not useful. Also a
max_tries of 10 ** 12 would not be very useful. But I can put the
burden of the problem on the caller of the function?
--
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof
[toc] | [prev] | [next] | [standalone]
| From | MRAB <python@mrabarnett.plus.com> |
|---|---|
| Date | 2015-06-03 19:12 +0100 |
| Message-ID | <mailman.119.1433355137.13271.python-list@python.org> |
| In reply to | #91976 |
On 2015-06-03 17:15, Cecil Westerhof wrote:
> Op Wednesday 3 Jun 2015 15:29 CEST schreef Chris Angelico:
>
>> On Wed, Jun 3, 2015 at 10:27 PM, Cecil Westerhof <Cecil@decebal.nl> wrote:
>>> def send_message(account_id, message, max_tries,
>>> terminate_program): error_msg = 'Something went wrong with: ' +
>>> message not_send = True tries = 0 while not_send: try:
>>> Core().update_status(account_id, message) except
>>> libturpial.exceptions.ServiceOverCapacity: tries += 1 print('Tried
>>> to send it {0} times'.format(tries)) if tries >= max_tries:
>>> terminate_program(error_msg) time.sleep(60) except:
>>> terminate_program(error_msg) else: not_send = False
>>>
>>> Is this a reasonable way to implement this, or is another way
>>> better? Well, maybe the timeout should be a parameter also. ;-)
>>
>> I'd skip the not_send flag and do the logic thusly:
>>
>> while True:
>> try:
>> update_status as above
>> break
>> except ServiceOverCapacity:
>> as above
>
> Yes that is much better. I now made it:
> def send_message(account_id, message, max_tries, give_error, wait_time = 60):
> error_msg = 'Something went wrong with: ' + message
> tries = 0
> while True:
> try:
> Core().update_status(account_id, message)
> break
> except libturpial.exceptions.ServiceOverCapacity:
> tries += 1
> print('Tried to send it {0} times'.format(tries))
> if tries >= max_tries:
> give_error(error_msg)
> return
> time.sleep(wait_time)
> except:
> give_error(error_msg)
> return
>
>> And I'd also skip the bare except clause. If you get any sort of
>> exception, whether it's a bug, a failure from libturpial, a network
>> error, or anything else, your code will just terminate with a bland
>> and useless message. Much better to simply let the exception bubble
>> up.
>
> I kept the except. I like to see the message that went wrong. ;-)
>
You're still swallowing unexpected exceptions.
If any exception apart from ServiceOverCapacity is raised, the bare
except will just call 'give_error' and then return.
If you try to interrupt the program (^C on Windows, ^D on Linux), that'll
also be ignored.
> Also, in my case give_error terminates the program, but it never hurts
> to make functionality generic, so I added return statements. Not
> break, because on error you should leave the function. Break would in
> this instance do the same, but I find this neater.
>
>
>>> Also the documentation of time.sleep says:
>>> The actual suspension time may be less than that requested because
>>> any caught signal will terminate the sleep() following execution
>>> of that signal’s catching routine.
>>>
>>> My program does not much else as sending the message. So I think it
>>> is not necessary to cover for this possibility. Are I assuming to
>>> much?
>>
>> I wouldn't worry too much about a signal cutting your sleep short;
>> it doesn't look to me as if "exactly sixty seconds" is all that
>> crucial here. If your program sleeps for 42.645 seconds and then
>> gets woken up by a signal, and you retry a bit sooner than you
>> otherwise would have, is it going to break anything? If not, just
>> ignore that possibility.
>
> Correct, so I did not assume to much. :-D
>
> Usually I check parameters. But I understood that is not the Python
> way. For example a wait_time of 1, or negative is not useful. Also a
> max_tries of 10 ** 12 would not be very useful. But I can put the
> burden of the problem on the caller of the function?
>
[toc] | [prev] | [next] | [standalone]
| From | Ethan Furman <ethan@stoneleaf.us> |
|---|---|
| Date | 2015-06-03 11:28 -0700 |
| Message-ID | <mailman.120.1433356162.13271.python-list@python.org> |
| In reply to | #91976 |
On 06/03/2015 09:15 AM, Cecil Westerhof wrote: > I kept the except. I like to see the message that went wrong. ;-) That's fine, but then add a `raise` after you print the error so you can see the reason that message failed. -- ~Ethan~
[toc] | [prev] | [next] | [standalone]
| From | Mark Lawrence <breamoreboy@yahoo.co.uk> |
|---|---|
| Date | 2015-06-03 21:37 +0100 |
| Message-ID | <mailman.126.1433363882.13271.python-list@python.org> |
| In reply to | #91976 |
On 03/06/2015 19:28, Ethan Furman wrote: > On 06/03/2015 09:15 AM, Cecil Westerhof wrote: > >> I kept the except. I like to see the message that went wrong. ;-) > > That's fine, but then add a `raise` after you print the error so you can > see the reason that message failed. > > -- > ~Ethan~ Why bother in the first place, especially when you're developing? Far easier to let the exception bubble up, or are we talking cross purposes? -- My fellow Pythonistas, ask not what our language can do for you, ask what you can do for our language. Mark Lawrence
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-06-04 08:00 +1000 |
| Message-ID | <mailman.134.1433368816.13271.python-list@python.org> |
| In reply to | #91976 |
On Thu, Jun 4, 2015 at 2:15 AM, Cecil Westerhof <Cecil@decebal.nl> wrote:
>> And I'd also skip the bare except clause. If you get any sort of
>> exception, whether it's a bug, a failure from libturpial, a network
>> error, or anything else, your code will just terminate with a bland
>> and useless message. Much better to simply let the exception bubble
>> up.
>
> I kept the except. I like to see the message that went wrong. ;-)
In that case, there's an easier way to deal with it: just raise a
different exception, and let them chain. Something like this:
>>> def send_message(msg):
... try: 1/0
... except: raise FailedMessageException(msg)
...
>>> class FailedMessageException(Exception): pass
...
>>> send_message("Test")
Traceback (most recent call last):
File "<stdin>", line 2, in send_message
ZeroDivisionError: division by zero
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in send_message
__main__.FailedMessageException: Test
But I'd still avoid the bare except, and use "except Exception:"
instead. I don't think you want to catch SystemExit in this way, for
instance. So here's how I'd write that code:
>>> def send_message(msg):
... try: 1/0
... except Exception as e: raise FailedMessageException(msg) from e
...
>>> send_message("Test")
Traceback (most recent call last):
File "<stdin>", line 2, in send_message
ZeroDivisionError: division by zero
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in send_message
__main__.FailedMessageException: Test
(Also, the use of "from" here causes a slightly different wording,
which I think is more appropriate. But that's minor.)
You get the report of which message failed, plus you get the complete
traceback from the original exception. Much MUCH more useful.
ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Ethan Furman <ethan@stoneleaf.us> |
|---|---|
| Date | 2015-06-03 16:15 -0700 |
| Message-ID | <mailman.138.1433373373.13271.python-list@python.org> |
| In reply to | #91976 |
On 06/03/2015 01:37 PM, Mark Lawrence wrote: > On 03/06/2015 19:28, Ethan Furman wrote: >> On 06/03/2015 09:15 AM, Cecil Westerhof wrote: >> >>> I kept the except. I like to see the message that went wrong. ;-) >> >> That's fine, but then add a `raise` after you print the error so you can >> see the reason that message failed. >> > > Why bother in the first place, especially when you're developing? Far easier to let the exception bubble up, or are we talking cross purposes? I think Cecil means he wants to see which twitter message failed to send. The rest of us would like to also have the error itself displayed. ;) -- ~Ethan~
[toc] | [prev] | [next] | [standalone]
| From | Cecil Westerhof <Cecil@decebal.nl> |
|---|---|
| Date | 2015-06-04 07:13 +0200 |
| Message-ID | <87r3psgioc.fsf@Equus.decebal.nl> |
| In reply to | #92012 |
Op Thursday 4 Jun 2015 01:15 CEST schreef Ethan Furman: > On 06/03/2015 01:37 PM, Mark Lawrence wrote: >> On 03/06/2015 19:28, Ethan Furman wrote: >>> On 06/03/2015 09:15 AM, Cecil Westerhof wrote: >>> >>>> I kept the except. I like to see the message that went wrong. ;-) >>> >>> That's fine, but then add a `raise` after you print the error so >>> you can see the reason that message failed. >>> >> >> Why bother in the first place, especially when you're developing? >> Far easier to let the exception bubble up, or are we talking cross >> purposes? > > I think Cecil means he wants to see which twitter message failed to > send. The rest of us would like to also have the error itself > displayed. ;) Correct. I display the error in the function I call. I also quit the program in the function I call. Is the correct thing to do, but if someone just want to continue after displaying the error, that should be possible also. That is why I choose to implement it this way. I should produce some docstring. ;-) -- Cecil Westerhof Senior Software Engineer LinkedIn: http://www.linkedin.com/in/cecilwesterhof
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web