@Override
    public void run() {
        try {
            backgroundJobServer.getJobSteward().notifyThreadOccupied();
            MDCMapper.loadMDCContextFromJob(job);
            performJob();
        } catch (Exception e) {
            if (isJobDeletedWhileProcessing(e)) {
                // nothing to do anymore as Job is deleted
                return;
            } else if (isJobServerStopped(e)) {
                updateJobStateToFailedAndRunJobFilters("Job processing was stopped as background job server has stopped", e);
                Thread.currentThread().interrupt();
            } else if (isJobNotFoundException(e)) {
                updateJobStateToFailedAndRunJobFilters("Job method not found", e);
            } else {
                updateJobStateToFailedAndRunJobFilters("An exception occurred during the performance of the job", e);
            }
        } finally {
            backgroundJobServer.getJobSteward().notifyThreadIdle();
            MDC.clear();
        }
    }
@Test
    void onFailureAfterAllRetriesExceptionIsLoggedToError() {
        Job job = aFailedJobWithRetries().withEnqueuedState(Instant.now()).build();
        when(backgroundJobServer.getBackgroundJobRunner(job)).thenReturn(null);

        BackgroundJobPerformer backgroundJobPerformer = new BackgroundJobPerformer(backgroundJobServer, job);
        final ListAppender<ILoggingEvent> logger = LoggerAssert.initFor(backgroundJobPerformer);
        backgroundJobPerformer.run();

        assertThat(logAllStateChangesFilter.getStateChanges(job)).containsExactly("ENQUEUED->PROCESSING", "PROCESSING->FAILED");
        assertThat(logger)
                .hasNoWarnLogMessages()
                .hasErrorMessage(String.format("Job(id=%s, jobName='failed job') processing failed: An exception occurred during the performance of the job", job.getId()));
    }