-1

I am trying to program a Python script on Apache on a Raspberry Pi. My script contains:

#!/usr/bin/env python3
print("Content-type: text/html\n\n")
print("<!DOCTYPE html>\n<head>")

# ... other code

try:
    with picamera.PiCamera() as camera:
       camera.capture('camera.jpg')
except Exception as error:
    errorMsg = error

The PiCamera code produced an error (because I am migrating some existing code to a new Pi and haven't moved the camera over yet). The error is caught, but Apache still produced a 500 error. The error log shows:

malformed header from script 'start.py': Bad header: * failed to open vchiq instanc

It seems that the PiCamera error output was piped to the Http output. Shouldn't this be fine, as my first print function has already output two blank lines? Does the error message mean that the PiCamera output being interpreted as Http headers? If so why?

Old Geezer
  • 14,854
  • 31
  • 111
  • 198
  • what happens if you remove all the code after the print statements? – jfs Dec 16 '15 at 20:20
  • The script works fine when the `try` block does not write out error messages, ie even if the `try` block results in the `except` block being executed, the web page is generated as expected. The "* failed to open vchiq instanc" is an error message from the `camera.capture` line because the running process is not in the group `video`. When I added www-data to group video, there's no more 500 error, even though the except block was run because I have no camera on the Pi, ie camera.capture failed and was caught successfully. – Old Geezer Dec 18 '15 at 05:06
  • Does it produce 500 http error if you print anything to stderr: `print('error', file=sys.stderr)`? If it does then [redirect `sys.stderr`](http://stackoverflow.com/a/22434262/4279). – jfs Dec 18 '15 at 05:16
  • Weird, I added `print('error',file=sys.stderr)` but there was no 500 error. Although I have solved my problem I am still puzzled. – Old Geezer Dec 18 '15 at 05:36

1 Answers1

0

Some webservers (i.e. Apache) buffers script output until script ends. sys.stdout.flush() doesn't help, as I can see.

You can take out non-printable code in separate script and call it like subprocess.call(['2nd script'], stdout = subprocess.PIPE, stderr = subprocess.PIPE) (or subprocess.DEVNULL)

Miamy
  • 2,162
  • 3
  • 15
  • 32
  • (1) you shouldn't need to move the code into a separate process. Catching exceptions should be enough (2) don't use `subprocess.call()` with `PIPE`, it may hang the child process i.e., use `DEVNULL` to discard the output. – jfs Dec 16 '15 at 20:19