Repository: appsmithorg/appsmith
File: app/server/appsmith-server/src/main/java/com/appsmith/server/helpers/ce/PluginScheduledTaskUtilsCEImpl.java (Java)

Code before:
public class PluginScheduledTaskUtilsCEImpl implements PluginScheduledTaskUtilsCE {
    private final String REMOTE_PLUGINS_FETCH_URL = "/api/v1/plugins";
    private final ConfigService configService;
    protected final PluginService pluginService;
    private final CloudServicesConfig cloudServicesConfig;

    private Mono<Map<PluginScheduledTaskCEImpl.PluginIdentifier, Plugin>> getRemotePlugins(Instant lastUpdatedAt) {
        return this.fetchPluginsFromCS(lastUpdatedAt, REMOTE_PLUGINS_FETCH_URL);
    }

    protected Mono<Map<PluginScheduledTaskCEImpl.PluginIdentifier, Plugin>> fetchPluginsFromCS(
            Instant lastUpdatedAt, String csApiPath) {
        final String baseUrl = cloudServicesConfig.getBaseUrl();
        if (!StringUtils.hasLength(baseUrl)) {
            return Mono.empty();
        }
        String lastUpdatedAtParam = lastUpdatedAt != null ? "&lastUpdatedAt=" + lastUpdatedAt : "";
        return configService.getInstanceId().flatMap(instanceId -> WebClientUtils.create(
                        baseUrl + csApiPath + "?instanceId=" + instanceId + lastUpdatedAtParam)
                .get()
                .exchangeToMono(clientResponse ->
                        clientResponse.bodyToMono(new ParameterizedTypeReference<ResponseDTO<List<Plugin>>>() {}))
                .map(listResponseDTO -> {
                    if (listResponseDTO.getData() == null) {
                        String errorMessage = listResponseDTO.getErrorDisplay();
                        log.error("Error fetching plugins from cloud-services. Error: {}", errorMessage);

                        // If there's an actual error message, propagate it as an error
                        if (errorMessage != null && !errorMessage.isEmpty()) {
                            throw new RuntimeException("Cloud Services error: " + errorMessage);
                        }

                        // Otherwise, return empty list (no plugins found)
                        return Collections.<Plugin>emptyList();
                    }
                    return listResponseDTO.getData();
                })
                .map(plugins -> {
                    // Parse plugins into map for easier manipulation
                    return plugins.stream()
                            .collect(Collectors.toMap(
                                    plugin -> new PluginScheduledTaskCEImpl.PluginIdentifier(
                                            plugin.getPluginName(), plugin.getVersion()),
                                    plugin -> plugin));
                }));
    }

    protected Mono<Void> updatePlugins(
            Mono<Map<PluginScheduledTaskCEImpl.PluginIdentifier, Plugin>> availablePluginsMono,
            Mono<Map<PluginScheduledTaskCEImpl.PluginIdentifier, Plugin>> newPluginsMono) {
        return Mono.zip(availablePluginsMono, newPluginsMono).flatMap(tuple -> {

Review comment (suggestion):
This is not required. The error would be logged (if present) by the run time exception that you are throwing in line 55

Code after:
public class PluginScheduledTaskUtilsCEImpl implements PluginScheduledTaskUtilsCE {
    private final String REMOTE_PLUGINS_FETCH_URL = "/api/v1/plugins";
    private final ConfigService configService;
    protected final PluginService pluginService;
    private final CloudServicesConfig cloudServicesConfig;

    private Mono<Map<PluginScheduledTaskCEImpl.PluginIdentifier, Plugin>> getRemotePlugins(Instant lastUpdatedAt) {
        return this.fetchPluginsFromCS(lastUpdatedAt, REMOTE_PLUGINS_FETCH_URL);
    }

    protected Mono<Map<PluginScheduledTaskCEImpl.PluginIdentifier, Plugin>> fetchPluginsFromCS(
            Instant lastUpdatedAt, String csApiPath) {
        final String baseUrl = cloudServicesConfig.getBaseUrl();
        if (!StringUtils.hasLength(baseUrl)) {
            return Mono.empty();
        }
        String lastUpdatedAtParam = lastUpdatedAt != null ? "&lastUpdatedAt=" + lastUpdatedAt : "";
        return configService.getInstanceId().flatMap(instanceId -> WebClientUtils.create(
                        baseUrl + csApiPath + "?instanceId=" + instanceId + lastUpdatedAtParam)
                .get()
                .exchangeToMono(clientResponse ->
                        clientResponse.bodyToMono(new ParameterizedTypeReference<ResponseDTO<List<Plugin>>>() {}))
                .map(listResponseDTO -> {
                    if (listResponseDTO.getData() == null) {
                        String errorMessage = listResponseDTO.getErrorDisplay();
                        // If there's an actual error message, propagate it as an error
                        if (errorMessage != null && !errorMessage.isEmpty()) {
                            throw new RuntimeException("Cloud Services error: " + errorMessage);
                        }

                        // Otherwise, return empty list (no plugins found)
                        return Collections.<Plugin>emptyList();
                    }
                    return listResponseDTO.getData();
                })
                .map(plugins -> {
                    // Parse plugins into map for easier manipulation
                    return plugins.stream()
                            .collect(Collectors.toMap(
                                    plugin -> new PluginScheduledTaskCEImpl.PluginIdentifier(
                                            plugin.getPluginName(), plugin.getVersion()),
                                    plugin -> plugin));
                }));
    }

    protected Mono<Void> updatePlugins(
            Mono<Map<PluginScheduledTaskCEImpl.PluginIdentifier, Plugin>> availablePluginsMono,
            Mono<Map<PluginScheduledTaskCEImpl.PluginIdentifier, Plugin>> newPluginsMono) {
        return Mono.zip(availablePluginsMono, newPluginsMono).flatMap(tuple -> {
            final Map<PluginScheduledTaskCEImpl.PluginIdentifier, Plugin> availablePlugins = tuple.getT1();
            final Map<PluginScheduledTaskCEImpl.PluginIdentifier, Plugin> newPlugins = tuple.getT2();