GDesktopAppInfo never failed in the most simple of the cases: when a desktop file or a command line app info was pointing to an invalid executable (for the context).
The reason for this is that we're launching all the programs using gio-launch-desktop which will always exist in a sane GLib installation, and thus our call to execvp won't ever fail on failure.
This was partially mitigated by not allowing to create a desktop app icon using a non-existent executable (even if not fully correctly) but still did not work in case a custom PATH was provided in the launch context.
To avoid this, use g_find_program_for_path() to find early if a program that we're about to launch is available, and if it's not the case return the same error that g_spawn_async_with_fds() would throw in such cases.
While this is slowing a bit our preparation phase, would avoid to leave to the exec function the job to find where our program is.
Add tests simulating this behavior.
This required split g_find_program_path() in g_find_program_for_path() that supports passing path arguments and providing a custom working directory.
Testing of g_find_program_for_path() implies adding a private symbol, so would be better when #2801 is fixed.
!3015 (merged) is very likely needed for some tests to pass.