Skip to content

Fix silent exception swallowing in C API factory functions#1006

Draft
Bert0ns wants to merge 4 commits into
projectM-visualizer:masterfrom
Bert0ns:bert0ns/fix-silent-exceptions
Draft

Fix silent exception swallowing in C API factory functions#1006
Bert0ns wants to merge 4 commits into
projectM-visualizer:masterfrom
Bert0ns:bert0ns/fix-silent-exceptions

Conversation

@Bert0ns

@Bert0ns Bert0ns commented Jul 1, 2026

Copy link
Copy Markdown

Currently, the C API factory functions projectm_create_with_opengl_load_proc and projectm_playlist_create wrap their instance creation logic in a blanket catch(...) block. If initialization fails and a standard exception is thrown (e.g. std::bad_alloc or any custom exception that derives from std::exception), the error is silently swallowed and a null pointer is returned without any log output. This makes diagnosing initialization failures extremely difficult for host applications.

Changes

  • Added a catch(const std::exception& e) clause to projectm_create_with_opengl_load_proc (in ProjectMCWrapper.cpp) to log the error message using LOG_ERROR before catching ....
  • Added the exact same fix to projectm_playlist_create (in PlaylistCWrapper.cpp), along with the necessary #include <Logging.hpp>.

These minimal changes ensure that any standard exceptions thrown during library instantiation are properly recorded by the project's internal logging framework.

I was trying to implement my own frontend but it kept crushing with no useful errors, so i thought i could make this improvement for the future generations

Copilot AI review requested due to automatic review settings July 1, 2026 00:05

This comment was marked as spam.

@kblaschke

Copy link
Copy Markdown
Member

Oh, looks like I've missed these when adding the logging API, thanks!

I'll let the build checks run, not expecting any failures.

@kblaschke

kblaschke commented Jul 6, 2026

Copy link
Copy Markdown
Member

Oh dang, looks like GitHub updated their NodeJS version on their actions once again... have to fix the workflow files first, please hold the line!

I also introduced an overload for the log function that takes is a char* as message, this is to prevent multiple bad_allocs when the errors surface towards the c api
@Bert0ns

Bert0ns commented Jul 6, 2026

Copy link
Copy Markdown
Author

Hi i'm sorry i noticed that the build or tests could fail, even if the nodejs version makes them fail without even trying.

  • Fix: I introduced a new Log(const char* message, LogLevel severity)
    overload in Logging.hpp / Logging.cpp . This allows the raw pointer to
    pass directly to the C callback without any heap allocation, guaranteeing exception safety inside the catch blocks. If we used the other one, Log(const std::string ...) there might be a chance of getting a bad_alloc exception, ruining everything. (this fix was suggested by Gemini, i think it makes sense)

  • Mocked libprojectM::logging in the tests, now they all pass:

    • this is beacuse the playlist module is architecturally separate and doesn't link to the core library in its unit tests.

@kblaschke

kblaschke commented Jul 6, 2026

Copy link
Copy Markdown
Member

Hi i'm sorry i noticed that the build or tests could fail, even if the nodejs version makes them fail without even trying.

Ah, alright! If you'd be so kind to rebase on master again, the build checks will run properly then, I've pushed a commit to fix the issues (also had to update to VS2026 on the Windows 2025 VMs).

* Fix: I introduced a new Log(const char* message, LogLevel severity)
  overload in  Logging.hpp / Logging.cpp . This allows the raw pointer to
  pass directly to the C callback without any heap allocation, guaranteeing exception safety inside the  catch  blocks. If we used the other one, Log(const std::string ...) there might be a chance of getting a bad_alloc exception, ruining everything. (this fix was suggested by Gemini, i think it makes sense)

Yeah, that's a sensible thing to do. If the process goes OOM, it's probably moot in any case, but if there's other issues it may at least get the message out.

@kblaschke kblaschke left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On a closer look, using the logging macros in the playlist library won't work due to the two libraries not sharing any code. The issue you've seen with the unit tests will also pop up for any application devs compiling both libraries as shared libraries. As stated in the code comment, on Windows this won't work due to the logger symbols not being exported. And even if they were, it may cause issues due to possibly different heaps being used, which can cause memory allocation issues.

Comment on lines +246 to +247
LOG_ERROR("projectm_playlist_create caught exception:");
LOG_ERROR(e.what());

@kblaschke kblaschke Jul 6, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that this might not work properly on some systems, especially Windows, as the logging symbols aren't exported.

I'd rather not cross-include the logging header from the core library in the playlist library.

In general, if you have to use ../ in the includes somewhere, it's probably not the right thing to do. the include paths for each subproject are specifically tailored in a way that only public headers of other libraries are available.

That said, options here are:

  • Remove logging in the playlist library. At instance creation, there's not much that may go wrong except for memory issues, in which case logging will most probably also fail.
  • Add a playlist-specific logging API to this library. Note that libprojectm and libprojectm-playlist are totally separate, independent libraries, and thus don't share singletons like the logging system. This is especially problematic on Windows, as different DLLs may not share the same heap and this might not work at all.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok thanks for the explanation, I realize that what I did is wrong. I guess the quick way for now is to remove the logging from the playlist lib.

I will try to come up with a better solution in the next couple of days (or weeks😭).

I still think giving the user some kind of message of the error would be nice. The reason I opened this PR is because of this. I was trying to implement my own frontend (flutter + a bit of vibe coding), but I couldn't get it to render the animations, it turns out that specifically those lines where I added the logging were returning a nullptr. With some AI debugging, it placed a brutal cout around those lines to print the actual error, that really helped me to solve the problem.

On second thought, maybe just having the logging from projectMWrapper.cpp might be enough, I will need to test that

@Bert0ns Bert0ns marked this pull request as draft July 6, 2026 18:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants