Re: [Tutor] Logging exceptions, but getting stderr output instead

2016-05-29 Thread Steven D'Aprano
On Wed, May 25, 2016 at 03:44:28PM -0400, Alex Hall wrote:
> You're not missing anything; I wasn't clear. I wasn't sure if raise or
> sys.exit(1) were the preferred ways, or if there was some other way I
> didn't know about. I've never had to force a script to halt before, at
> least not one I mean to schedule to run on its own once a day, so wanted to
> check that those are indeed the recommended ways.

raise and sys.exit() do different things, which both happen to result in 
the script halting.

`raise` re-raises the current exception, that's all. What happens from 
that point depends: the exception could be caught by another 
try...except handler, or it might not be. If it isn't caught by 
anything, the interpreter will print a traceback and error message, and 
then halt with a non-zero exit code.

`sys.exit` will exit. Technically it actually raises an exception, 
SystemExit, which can also be caught like any other exception, but 
normally it won't be. (I can go into detail about exactly when it 
will be caught if you like.) If you call sys.exit with no argument, or 
with argument 0, then it will halt the script with exit code 0 
("success") and no traceback. Any other integer code will set the exit 
code to that value, and any string value will print that string to 
stderr and then exit with a non-zero exit code.


-- 
Steve
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Logging exceptions, but getting stderr output instead

2016-05-29 Thread Steven D'Aprano
On Wed, May 25, 2016 at 02:11:01PM -0400, Alex Hall wrote:

> As a quick aside, is there an easy way to halt script execution for some
> exceptions? Right now, catching them means that execution continues, but I
> sometimes want to log the problem and then abort the script, as the error
> means it shouldn't continue. Thanks.

In general you shouldn't fill your code with exception handling code if 
you can avoid it. You should only catch exceptions that you can handle and 
recover from. It's okay to log them right there, but since it's a 
recoverable error it should be a warning, not an error.

You should generally not catch fatal errors (except once, see below). If 
you must catch them, to decide whether or not they are fatal, then don't 
log them at the point you caught it, just re-raise using the base 
"raise" statement.

Finally, you should wrap your entire script in a single try...except to 
catch all the fatal exceptions in one go, log them, and exit. One way is 
this:


# Run the main script.
if __name__ == '__main__':
try:
main()
except Exception:
logging.exception("message")
sys.exit(error_code)


which will log an Error with "message", and the details of the exception 
including the traceback before exiting.

An alternative to a try...except block will be to set the excepthook 
before running main().

https://docs.python.org/3/library/sys.html#sys.excepthook

As always, it's okay to break these rules carefully and after giving 
them due thought. But if you find yourself calling sys.exit dozens of 
times from wildly-separate parts of your code, you're probably doing it 
wrong.


-- 
Steve
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Logging exceptions, but getting stderr output instead

2016-05-26 Thread Terry Carroll

On Wed, 25 May 2016, Alex Hall wrote:


You're not missing anything; I wasn't clear. I wasn't sure if raise or
sys.exit(1) were the preferred ways, or if there was some other way I
didn't know about.


If you're aborting because of the exception after unsuccessfully trying to 
handle it, you can always just use "raise" with no operands, which will 
re-raise the underlying exception. That's what I usually do:


try:
1/0
except ZeroDivisionError:
print "oops."
raise

prints:

oops.
Traceback (most recent call last):
  File "[...]\test.py", line 2, 
in 

1/0
ZeroDivisionError: integer division or modulo by zero

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Logging exceptions, but getting stderr output instead

2016-05-25 Thread Alex Hall
You're not missing anything; I wasn't clear. I wasn't sure if raise or
sys.exit(1) were the preferred ways, or if there was some other way I
didn't know about. I've never had to force a script to halt before, at
least not one I mean to schedule to run on its own once a day, so wanted to
check that those are indeed the recommended ways.

On Wed, May 25, 2016 at 3:37 PM, Alan Gauld via Tutor 
wrote:

> On 25/05/16 19:11, Alex Hall wrote:
>
> > As a quick aside, is there an easy way to halt script execution for some
> > exceptions? Right now, catching them means that execution continues, but
> I
> > sometimes want to log the problem and then abort the script, as the error
> > means it shouldn't continue. Thanks.
>
> I'm not sure what the issue is here.
> Can't you just exit in the normal fashion using
>
> sys.exit()
> or
> raise SystemExit?
>
> I feel I must be missing something?
>
> --
> Alan G
> Author of the Learn to Program web site
> http://www.alan-g.me.uk/
> http://www.amazon.com/author/alan_gauld
> Follow my photo-blog on Flickr at:
> http://www.flickr.com/photos/alangauldphotos
>
>
> ___
> Tutor maillist  -  Tutor@python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>



-- 
Alex Hall
Automatic Distributors, IT department
ah...@autodist.com
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Logging exceptions, but getting stderr output instead

2016-05-25 Thread Alex Hall
Well, I found the major problem: I had
logging.exception()
not
logger.exception()
All I can say is, with the screen reader I'm using, they sound similar.
Things are now working as expected. I'm still wondering about stopping
execution, though: call exit(), raise, or some other way?


On Wed, May 25, 2016 at 2:11 PM, Alex Hall  wrote:

> Hello again list,
> I didn't expect to be back so soon. :) I'm trying to log my new script,
> and logger.info() works fine. However, logger.exception() doesn't; I see
> the exception print to stderr, and it never appears in the log. Oddly, info
> messages after that appear in the shell and in my log, whereas normally
> they are only in the log. Here's my logger setup:
>
> logger = logging.getLogger(appName)
> logger.setLevel(logging.DEBUG)
> infoLogFormatter = logging.Formatter("%(asctime)s\n%(name)s,
> %(levelname)s: %(message)s", datefmt = "%I:%M:%S %p, %B %d, %Y")
> infoLogFileName = appName+".log"
> infoFileHandler = logging.FileHandler(infoLogFileName, mode="w")
> infoFileHandler.level = logging.INFO
> infoFileHandler.setFormatter(infoLogFormatter)
> logger.addHandler(infoFileHandler)
>
> Then, I deliberately called a non-existant function:
>
> for rep in reps:
>  try:
>   workbook = xlsxwriter.Workbook(workbookName)
>   worksheet = workbook.addWorksheet(rep.name) #should be add_worksheet,
> so this errors out
>  except:
>   logging.exception("Error generating spreadsheet for {name}".format(name=
> rep.name))
>
> The string I pass to logging.exception, along with the stack trace, print
> to the command line and not to my log file. Other logging.info() calls
> also print to the command line, but they also appear in the log. I haven't
> done much with logging before, and what I have done has been debug only,
> never exceptions. The resolution to this will likely be obvious, but when I
> looked it up, I found only information about how to log exceptions. No one
> seems to have the problem of exceptions not being logged correctly.
>
> As a quick aside, is there an easy way to halt script execution for some
> exceptions? Right now, catching them means that execution continues, but I
> sometimes want to log the problem and then abort the script, as the error
> means it shouldn't continue. Thanks.
>
>
> --
> Alex Hall
> Automatic Distributors, IT department
> ah...@autodist.com
>



-- 
Alex Hall
Automatic Distributors, IT department
ah...@autodist.com
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Logging exceptions, but getting stderr output instead

2016-05-25 Thread Peter Otten
Alex Hall wrote:

> Hello again list,
> I didn't expect to be back so soon. :) I'm trying to log my new script,
> and logger.info() works fine. However, logger.exception() doesn't; I see
> the exception print to stderr, and it never appears in the log. Oddly,
> info messages after that appear in the shell and in my log, whereas
> normally they are only in the log. Here's my logger setup:
> 
> logger = logging.getLogger(appName)
> logger.setLevel(logging.DEBUG)
> infoLogFormatter = logging.Formatter("%(asctime)s\n%(name)s,
> %(levelname)s: %(message)s", datefmt = "%I:%M:%S %p, %B %d, %Y")
> infoLogFileName = appName+".log"
> infoFileHandler = logging.FileHandler(infoLogFileName, mode="w")
> infoFileHandler.level = logging.INFO
> infoFileHandler.setFormatter(infoLogFormatter)
> logger.addHandler(infoFileHandler)
> 
> Then, I deliberately called a non-existant function:
> 
> for rep in reps:
>  try:
>   workbook = xlsxwriter.Workbook(workbookName)
>   worksheet = workbook.addWorksheet(rep.name) #should be add_worksheet, so
> this errors out
>  except:
>   logging.exception("Error generating spreadsheet for {name}".format(name=
> rep.name))

That should be logger.exception(...); logging.exception() logs to the root 
logger.

Unless you know what you are doing I'd still suggest that you add your 
handler(s) to the root logger. In most cases calling logging.basicConfig() 
is probably good enough...

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Logging exceptions, but getting stderr output instead

2016-05-25 Thread Alan Gauld via Tutor
On 25/05/16 19:11, Alex Hall wrote:

> As a quick aside, is there an easy way to halt script execution for some
> exceptions? Right now, catching them means that execution continues, but I
> sometimes want to log the problem and then abort the script, as the error
> means it shouldn't continue. Thanks.

I'm not sure what the issue is here.
Can't you just exit in the normal fashion using

sys.exit()
or
raise SystemExit?

I feel I must be missing something?

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor