Catch an error in an automation

I’m using an automation that uses media_player.play_media with a file path. But sometimes, the media player (kodi) does not find the file and returns an error. Can I catch this error in the automation and react to it?
Something like: If error, then send error message as notification to kodi. So I would see immediately what happened and not only when I go to the trace of the automation.

The only way to do this is to write a python script with a try except. Otherwise, native HA does not have this ability.

Can’t the automation look at the state of the media player if it’s still idle after a few seconds then it failed.

Perhaps this won’t work if you play something already when this automation runs.

OK, thank you!

That’s a good idea. I won’t be able to see the message of the error text, but at least I know that HA tried to play the file and was not successful. Thanks :slight_smile:

Here is Hellis81’s suggestion implemented as a script.

Change the values of the three variables to match whatever you have. It tests if the media_player is playing and the current song is what you requested. The script will post a persistent notification if the request to play the song succeeded or failed. Feel free to modify it to suit your needs.

script:
  media_player_test:
    alias: Media Player Test
    sequence:
    - variables:
        player: 'media_player.your_player'
        song: 'your_song.mp3'
        song_url: 'media-source://media_source/local/{{ song }}'

    - service: media_player.play_media
      target:
        entity_id: '{{ player }}'
      data:
        media_content_type: music
        media_content_id: '{{ song_url }}'

    - wait_template: "{{ is_state(player, 'playing') and song in state_attr(player, 'media_content_id') }}"
      timeout: 5

    - choose:
      - conditions: "{{ not wait.completed }}"
        sequence:
        - service: persistent_notification.create
          data:
            title: '{{ this.attributes.friendly_name }}'
            message: "Failure: Timed out after 5 seconds."
      default:
      - service: persistent_notification.create
        data:
          title: '{{ this.attributes.friendly_name }}'
          message: "Success: {{ song }} is playing."

I tested it by unplugging the media_player so its state became unavailable. Playing to it resulted in a timeout after 5 seconds and a notification that the attempt failed. Then I plugged it in and played a song. While the song was playing, I executed the script to play another song. The other song played and I received a notification that the script succeeded.

Are you sure that will run when there’s an exception? Looking at the code, there is nothing that stops an exception here and raises it as an error. Exceptions stop scripts in their tracks.

Good point. I performed another test, attempting to play a non-existent file.

I get an error message in the log:

Failed to cast media http://redacted:8123/media/local/zilch.mp3?authSig=redacted from internal_url (http://redacted:8123). Please make sure the URL is: Reachable from the cast device and either a publicly resolvable hostname or an IP address

I also get a persistent_notification from the script reporting the attempt failed.

Screenshot from 2021-12-15 11-48-58

I don’t know if this failure scenario is identical to what der-optimist is experiencing (where kodi fails to find the file) but it seems to work in this case.

Does that error have python code below it? If yes, then it’s an exception. If no, then it’s an error. I have no idea if Kodi produces an exception or error. It uses aiohttp or jsonrpc_async, so if it’s an exception it would come from that lib.

The error message didn’t contain any python code. In this test, it was a known failure case (file not found) that was cleanly trapped (as opposed to an unknown causing an exception and a code dump). The integration used for my test speaker was Google Cast.

If the Kodi integration is responding with an exception then, you’re right, this script won’t work. If Kodi is causing an exception, for a garden-variety ‘file not found’, then der-optimist should post it as an Issue (because it should be able to gracefully handle this case).

I’m not at home at the moment, so I can not test it right now. But in the trace of the automation, I saw in red color the error message that was returned from kodi (json format), but no python code. So I do not think that the kodi integration caused an exception.

In that case, the example I posted will meet your requirements. It’s capable of informing you when the media_player failed/succeeded to play the chosen song.

1 Like

I’m at home now and just to make it complete, I want to show the trace to you.

I will implement the proposal of @123 and if I’m interested in the text of the error message, I can look in the trace of the automation.
Thanks for your help

Yeah, that’s an exception. I don’t think you’ll get this to work the way it currently is. You may be able to if you separate that specific service call into it’s own script and employ 123’s automation calling the script instead. Make sure the script is set to parallel so that it’s running in it’s own thread. IIRC you also should be using script.turn_on instead of script.whatever_the_name_is so that the actions don’t wait for the script to complete.

Follow petro’s advice and also report Kodi’s exception as an Issue on GitHub. It should be able to handle the problem more gracefully than throwing an exception.

Just to make sure, you mean the kodi integration of HA should handle the problem more gracefully?
So this is the right place to report the issue?

Old topic but -
If you set a variable as error = True
then do your action
then set error = False

If the action fails, error stays = True
If used in a secondary script, add the option “Continue_on_error=True”

Code:

alias: Set AC Status (aux)
sequence:
  - service: input_boolean.turn_on
    target:
      entity_id:
        - input_boolean.ac_error
    data: {}
  - service: climate.set_swing_mode
    data:
      swing_mode: "off"
    target:
      entity_id: climate.mzgn
  - service: input_boolean.turn_off
    target:
      entity_id:
        - input_boolean.ac_error
    data: {}
mode: single
alias: Set AC Status
sequence:
  - service: script.check_ac_status
    continue_on_error: true
    data: {}
  - if:
      - condition: state
        entity_id: input_boolean.ac_error
        state: "on"
    then:
      - service: notify.mobile_app_pixel
        data:
          message: Error=True
    else:
      - service: notify.mobile_app_pixel
        data:
          message: Error=False
mode: single

Thank you! This helped me make my Sonos-Alarm (calendar driven) more robust and less likely to fail because the radio service got disabled, needs reauthorization, the internet connection is down…

alias: Play YouFM in Bedroom and Test, Failure ==> OneLoveMix
sequence:
  - variables:
      player: media_player.sonos_bedroom
      media_content_id: FV:2/37
      media_content_type: favorite_item_id
      title: You FM
      check_string: youfm
  - service: media_player.play_media
    continue_on_error: true
    target:
      entity_id: media_player.sonos_bedroom
    data:
      media_content_id: FV:2/37
      media_content_type: favorite_item_id
    metadata:
      title: YOU FM
      thumbnail: https://cdn-profiles.tunein.com/s24878/images/logoq.png?t=160821
      media_class: genre
      children_media_class: null
      navigateIds:
        - {}
        - media_content_type: favorites
          media_content_id: ""
        - media_content_type: favorites_folder
          media_content_id: object.item.audioItem.audioBroadcast
  - wait_template: >-
      {{ is_state(player, 'playing') and check_string in state_attr(player,
      'media_content_id') }}
    timeout: "7"
    continue_on_timeout: true
  - choose:
      - conditions:
          - condition: template
            value_template: "{{ not wait.completed }}"
        sequence:
          - service: persistent_notification.create
            data:
              title: Radio fehlgeschlagen
              message: Playing OneLoveMix instead
          - service: media_player.play_media
            data:
              entity_id: media_player.sonos_bedroom
              media_content_type: music
              media_content_id: http://ip:port/local/OneLoveMix.mp3
    default:
      - service: persistent_notification.create
        data:
          title: Radio erfolgreich abgespielt
          message: "Success: {{ title }} is playing."
        enabled: false
  - variables:
      script:
        error: >-
          {{ is_state(player, 'playing') and check_string in
          state_attr(player,'media_content_id') }}
    enabled: true
  - stop: End
    response_variable: script
    enabled: true
fields: {}
mode: single
icon: mdi:radio