core: camera.record service causes exception

The problem

A lot of my mp4 recordings become corrupt with the latest update. The only error I can see is these exceptions in the log, I guess they are connected to the issue.

What version of Home Assistant Core has the issue?

core-2022.7.5

What was the last working version of Home Assistant Core?

No response

What type of installation are you running?

Home Assistant Container

Integration causing the issue

stream

Link to integration documentation on our website

https://www.home-assistant.io/integrations/stream/

Diagnostics information

No response

Example YAML snippet

No response

Anything in the logs that might be useful for us?

2022-07-17 20:32:16 ERROR (MainThread) [homeassistant.core] Error executing service: <ServiceCall camera.record (c:01G86PWSWGBYSS12PPADZ5JMMZ): device_id=['c98d33e1ba0bce82a35d9da14c45e42e'], duration=15, lookback=2, filename=Template("/media/record1.mp4")>
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/core.py", line 1731, in catch_exceptions
    await coro_or_task
  File "/usr/src/homeassistant/homeassistant/core.py", line 1750, in _execute_service
    await cast(Callable[[ServiceCall], Awaitable[None]], handler.job.target)(
  File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 204, in handle_service
    await service.entity_service_call(
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 680, in entity_service_call
    future.result()  # pop exception if have
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 930, in async_request_call
    await coro
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 717, in _handle_entity_call
    await result
  File "/usr/src/homeassistant/homeassistant/components/camera/__init__.py", line 1017, in async_handle_record_service
    await stream.async_record(
  File "/usr/src/homeassistant/homeassistant/components/stream/__init__.py", line 514, in async_record
    await recorder.async_record()
  File "/usr/src/homeassistant/homeassistant/components/stream/recorder.py", line 166, in async_record
    os.rename(self.video_path + ".tmp", self.video_path)
FileNotFoundError: [Errno 2] No such file or directory: '/media/record1.mp4.tmp' -> '/media/record1.mp4'

Additional information

No response

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 27 (25 by maintainers)

Most upvoted comments

There’s already debug logging about the recording starting. It seems like info is generally discouraged? https://github.com/home-assistant/core/pull/73107#discussion_r891277767 I’ll add that error message in there and then put a blurb in the docs.

@uvjustin yeah, I agree. Even if you did protect against it, it still would be unexpected (two streams writing to the same file serially). I noticed the example includes the entity id kind of showing the point that there is only so much you can do here to ensure uniqueness:

filename: '/tmp/{{ entity_id.name }}_{{ now().strftime("%Y%m%d-%H%M%S") }}.mp4'

So, yeah, a warning in the documentation seems like a good idea.

You could also consider:

  • Adding info logging about the recording starting, so the user will see it happening twice if the look in the logs
  • Adding detail to the error message (“Error renaming file: <…>. There are likely multiple calls to record to the same file”)

@allenporter Do you think this is worth guarding against? Since it would be on different streams, an implementation would involve some kind of class level synchronizer. I’m inclined to just warn against this usage in the docs.

It seems to me that for some reason your service is getting called twice simultaneously. We don’t use a lock in the service, but there’s a section that checks if the recorder is already working. However, it’s possible for two simultaneous calls to both get past that section. Is there any other service you can call to see if it also gets called twice?

Hmm, I think I might have an idea what might be causing this. I’ll prepare a PR to see if it fixes the issue.