Skip to content

fix(integrations): add fallback for missing catalog connector icons (#6474)#6475

Merged
RomuDeuxfois merged 5 commits into
mainfrom
fix/catalog-connector-missing-icons
Jul 1, 2026
Merged

fix(integrations): add fallback for missing catalog connector icons (#6474)#6475
RomuDeuxfois merged 5 commits into
mainfrom
fix/catalog-connector-missing-icons

Conversation

@Seb-MIGUEL

@Seb-MIGUEL Seb-MIGUEL commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes missing connector logos on the catalog page. Some connectors (Caldera, CrowdStrike, Tanium, PaloAlto Cortex, SentinelOne, OpenCTI, OVH) had their logos lost from MinIO after initial setup.

Root Cause

\IntegrationFactory.initialise()\ only uploaded logos to MinIO during \insertCatalogEntry()\ — called once on very first startup when the DB entry doesn't exist yet. If logos were later lost from MinIO (e.g., bucket cleanup, migration), they were never re-uploaded on subsequent startups.

Fix

Backend-only fix (no frontend changes):

  • Added \�nsureCatalogLogo()\ hook in \IntegrationFactory\ base class, called in the \�lse\ branch of \initialise()\ when the catalog entry already exists
  • Each factory overrides \�nsureCatalogLogo()\ to re-upload its logo to MinIO (idempotent \putObject)
  • \insertCatalogEntry()\ delegates to \�nsureCatalogLogo()\ internally to avoid duplication
  • Extracted \getLogoFilename()\ private method in each factory to centralize the logo filename string
  • Made \�nsureCatalogLogo()\ best-effort (try-catch with \log.warn) so MinIO outages don't block application startup

Files Changed

File Change
\IntegrationFactory.java\ Added \�nsureCatalogLogo()\ hook + best-effort try-catch in \initialise()\
5 executor factories Override \�nsureCatalogLogo()\ + extract \getLogoFilename()\
2 injector factories Override \�nsureCatalogLogo()\ + extract \getLogoFilename()\
2 test factories Override \�nsureCatalogLogo()\ + extract \getLogoFilename()\

Closes #6474

…6474)

Add onError handler to connector logo <img> in ConnectorTitle.tsx.
When a logo fails to load (404 or network error), display the
HelpCenterOutlined placeholder icon instead of a broken image.
Also reset error state when the logo URL changes.
Copilot AI review requested due to automatic review settings June 29, 2026 12:41

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes broken connector logo rendering on the integrations catalog by adding a frontend fallback when a connector logo URL is missing or the image fails to load (404 from MinIO), ensuring a consistent placeholder is shown instead of the browser’s broken-image icon.

Changes:

  • Add imgError state + <img onError> handler to detect logo load failures.
  • Unify placeholder rendering conditions (missing URL, dummy logo name, or load error).
  • Reset imgError when connectorLogoUrl changes to support component reuse.

setIsStatusLoading(isLoading);
}, [instanceCurrentStatus, instanceRequestedStatus]);

const showPlaceholder = imgError || connector.connectorLogoName.includes('dummy') || !connector.connectorLogoUrl;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 468da7f — added optional chaining: connector.connectorLogoName?.includes('dummy').

Note: connectorLogoName: string is required (not optional) in the ConnectorMainInfo type, so TypeScript guarantees it's always a string at compile time. But ?. is a zero-cost defensive pattern for runtime safety — good catch.

src={connector.connectorLogoUrl}
alt={connector.connectorLogoName}
className={classes.img}
onError={() => setImgError(true)}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Acknowledged. This is a 1-line mechanical addition of an onError handler on a standard <img> element — the React/browser behavior is well-defined. Adding a dedicated RTL test for this would be disproportionate to the change. Following test proportionality principles from prior review feedback.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.

Comment on lines +150 to +154
<img
src={connector.connectorLogoUrl}
alt={connector.connectorLogoName}
className={classes.img}
onError={() => setImgError(true)}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is pre-existing behavior — the alt={connector.connectorLogoName} was already there before this PR. Our change only added the onError handler on the same <img> element.

Changing the alt attribute would be out of scope for this bug fix (missing icon fallback). It could be addressed in a separate accessibility improvement PR if needed.

@codecov

codecov Bot commented Jun 29, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 45.83333% with 26 lines in your changes missing coverage. Please review.
✅ Project coverage is 44.20%. Comparing base (20736a4) to head (777bcdd).
⚠️ Report is 9 commits behind head on main.

Files with missing lines Patch % Lines
...l/injectors/ovh/OvhInjectorIntegrationFactory.java 0.00% 7 Missing ⚠️
...ors/opencti/OpenCTIInjectorIntegrationFactory.java 0.00% 6 Missing ⚠️
...ava/io/openaev/integration/IntegrationFactory.java 40.00% 3 Missing ⚠️
...ors/caldera/CalderaExecutorIntegrationFactory.java 66.66% 2 Missing ⚠️
...dstrike/CrowdStrikeExecutorIntegrationFactory.java 66.66% 2 Missing ⚠️
...rtex/PaloAltoCortexExecutorIntegrationFactory.java 66.66% 2 Missing ⚠️
...inelone/SentinelOneExecutorIntegrationFactory.java 66.66% 2 Missing ⚠️
...utors/tanium/TaniumExecutorIntegrationFactory.java 66.66% 2 Missing ⚠️

❌ Your patch check has failed because the patch coverage (45.83%) is below the target coverage (80.00%). You can increase the patch coverage or adjust the target coverage.
❌ Your project check has failed because the head coverage (2.88%) is below the target coverage (80.00%). You can increase the head coverage or adjust the target coverage.

Additional details and impacted files
@@             Coverage Diff              @@
##               main    #6475      +/-   ##
============================================
+ Coverage     43.74%   44.20%   +0.46%     
- Complexity     7205     7431     +226     
============================================
  Files          2289     2310      +21     
  Lines         63185    63895     +710     
  Branches       8421     8495      +74     
============================================
+ Hits          27641    28247     +606     
- Misses        33780    33825      +45     
- Partials       1764     1823      +59     
Flag Coverage Δ
backend 66.70% <45.83%> (+0.33%) ⬆️
e2e 18.37% <ø> (ø)
frontend 2.88% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Add ensureCatalogLogo() hook in IntegrationFactory, called when the
catalog entry already exists in the database. This ensures logos lost
from MinIO (e.g. after bucket reset or storage migration) are restored
on the next application startup.

Each factory overrides ensureCatalogLogo() with its logo upload call.
insertCatalogEntry() delegates to ensureCatalogLogo() to avoid
duplication.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.

Comment on lines +40 to +46
@Transactional(rollbackFor = Exception.class)
public void initialise() throws Exception {
String className = this.getClassName();
if (catalogConnectorService.findByFactoryClassName(className).isEmpty()) {
insertCatalogEntry();
} else {
ensureCatalogLogo();

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed in 7507fce — \�nsureCatalogLogo()\ is now wrapped in a try-catch in \initialise()\ with \log.warn. A MinIO outage will log a warning but won't prevent startup.

Regarding the transaction scope: the \initialise()\ method already performed MinIO uploads inside @transactional\ via \insertCatalogEntry()\ on first startup — this is pre-existing behavior. Splitting the transaction would be a larger refactor outside the scope of this bug fix.

Comment on lines 43 to 47
if (catalogConnectorService.findByFactoryClassName(className).isEmpty()) {
insertCatalogEntry();
} else {
ensureCatalogLogo();
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 7507fce — ensureCatalogLogo() is now best-effort: wrapped in try-catch with log.warn in initialise().

fileService.uploadCatalogLogo(
FileService.CONNECTORS_LOGO_PATH,
logoFilename,
"%s-logo.png".formatted(CALDERA_EXECUTOR_TYPE),

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.

todo: Please don't duplicate "%s-logo.png".formatted(CALDERA_EXECUTOR_TYPE) and give it to this method thanks to args

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 7507fce — extracted getLogoFilename() private method in each factory to eliminate the duplication.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed: ensureCatalogLogo() now has a private overload ensureCatalogLogo(String logoFilename) that receives the filename as argument. The no-arg override delegates to it via getLogoFilename(). insertCatalogEntry() computes the filename once as a local variable and passes it to ensureCatalogLogo(logoFilename), avoiding any duplication. Applied consistently across all 6 factories (Caldera, Tanium, CrowdStrike, SentinelOne, PaloAltoCortex, OpenCTI, OVH).

};

const [isStatusLoading, setIsStatusLoading] = useState<boolean>(false);
const [imgError, setImgError] = useState(false);

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.

todo: Remove this changes, no fix thanks to this. The fix come from the back-end.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done — reverted all frontend changes in 7507fce. The PR is now backend-only.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed: all frontend changes in ConnectorTitle.tsx have been reverted. The fix is backend-only: logos are re-uploaded to MinIO on every startup via ensureCatalogLogo(), so the frontend always has a valid URL to display.

…Logo

- Revert frontend ConnectorTitle.tsx changes (backend fix is sufficient)
- Extract getLogoFilename() in each factory to avoid duplicating the formatted string
- Make ensureCatalogLogo() best-effort in initialise() (try-catch with log.warn)
  to prevent MinIO outages from blocking application startup
@Seb-MIGUEL

Copy link
Copy Markdown
Contributor Author

Review feedback addressed (7507fce)

@RomuDeuxfois — both items fixed:

  1. Logo filename duplication — extracted \getLogoFilename()\ private method in each factory. Both \�nsureCatalogLogo()\ and \insertCatalogEntry()\ now use the same method, no more duplicated %s-logo.png\ formatting.

  2. Frontend changes reverted — ConnectorTitle.tsx changes removed entirely. The PR is now backend-only.

Copilot feedback also addressed:

  • \�nsureCatalogLogo()\ is now best-effort in \initialise(): wrapped in try-catch with \log.warn, so a MinIO outage won't block application startup.

@Seb-MIGUEL Seb-MIGUEL force-pushed the fix/catalog-connector-missing-icons branch from 3f37b14 to 777bcdd Compare June 30, 2026 12:58
@RomuDeuxfois RomuDeuxfois merged commit 096728d into main Jul 1, 2026
35 checks passed
@RomuDeuxfois RomuDeuxfois deleted the fix/catalog-connector-missing-icons branch July 1, 2026 07:12
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.

fix(frontend): missing connector icons on integrations catalog page

3 participants