@Override
    public Result reconcile(Request request) {
        client.fetch(Theme.class, request.name())
            .ifPresent(theme -> {
                if (isDeleted(theme)) {
                    cleanUpResourcesAndRemoveFinalizer(request.name());
                    return;
                }
                addFinalizerIfNecessary(theme);
                themeSettingDefaultConfig(theme);
                reconcileStatus(request.name());
            });
        return new Result(false, null);
    }
@Test
    void reconcileDeleteRetryWhenThrowException() {
        Theme theme = fakeTheme();

        Path testWorkDir = tempDirectory.resolve("reconcile-delete");
        when(themeRoot.get()).thenReturn(testWorkDir);

        final ThemeReconciler themeReconciler =
            new ThemeReconciler(extensionClient, themeRoot, systemVersionSupplier);

        final int[] retryFlags = {0};
        when(extensionClient.fetch(eq(Setting.class), eq("theme-test-setting")))
            .thenAnswer((Answer<Optional<Setting>>) invocation -> {
                retryFlags[0]++;
                // retry 2 times
                if (retryFlags[0] < 2) {
                    return Optional.of(new Setting());
                }
                throw new RetryException("retry exception.");
            });

        String settingName = theme.getSpec().getSettingName();
        assertThatThrownBy(
            () -> themeReconciler.reconcile(new Reconciler.Request(theme.getMetadata().getName())))
            .isInstanceOf(RetryException.class)
            .hasMessage("retry exception.");

        verify(extensionClient, times(2)).fetch(eq(Setting.class), eq(settingName));
    }