Check for nonzero exit codes on subprocesses

This is part of the Semicolon&Sons Code Diary - consisting of lessons learned on the job. You're in the dumb-mistakes-and-gotchas category.

Last Updated: 2024-11-21

I got some difficult-to-diagnose errors with the following code:

Specifically the function calling convert_music_xml_to_midi failed because the midi file was not available:

def convert_music_xml_to_midi(file_path: str, output_directory: str) -> str:
    converted_file_path = output_directory + '/temp.mid'
    process = subprocess.Popen(
        ["mscore", "-o", converted_file_path, file_path],
        stdout=subprocess.DEVNULL,
        stderr=subprocess.DEVNULL)
    process.wait()

    return converted_file_path

When I called the same linux command in the command line, it also failed.

$ muscore -o file.mid file.mxl

I was able to be aware of this fact by looking at its exit code:

$ echo $?
42 # can't remember actual code, just guessing

The fix in my Python code that shelled out was to check for non-zero exit codes before moving onwards:

def convert_music_xml_to_midi(file_path: str, output_directory: str) -> str:
    ...
    if process.wait() != 0:
        raise Exception("Problem executing mscore subprocess")

    return converted_file_path