Repository: TabbyML/tabby
File: ee/tabby-webserver/src/service/background_job/mod.rs (Rust)

Code before:
        BackgroundJobEvent::SchedulerGithubGitlabRepository(_) => {
            "Github/Gitlab repository synchronize"
        }
        BackgroundJobEvent::SyncThirdPartyRepositories(_) => "Integration synchronize",
        BackgroundJobEvent::WebCrawler(_) => "Web crawler",
        BackgroundJobEvent::IndexGarbageCollection => "Index garbage collection",
        BackgroundJobEvent::Hourly => "Hourly",
        BackgroundJobEvent::Daily => "Daily",
    }
}

async fn notify_job_error(
    notification_service: Arc<dyn NotificationService>,
    err: &str,
    event: &BackgroundJobEvent,
    id: i64,
) {
    warn!("job {:?} failed: {:?}", event, err);
    let name = background_job_notification_name(event);
    if let Err(err) = notification_service
        .create(
            NotificationRecipient::Admin,
            &format!(
                r#"Background job failed

Job `{}` has failed.

Please check the log at [Jobs Detail](/jobs/detail?id={}) to identify the underlying issue.
"#,
                name,
                id.as_id()
            ),
        )
        .await
    {
        warn!("Failed to send notification: {:?}", err);
    }
}

pub async fn start(
    db: DbConn,
    job_service: Arc<dyn JobService>,
    git_repository_service: Arc<dyn GitRepositoryService>,
    third_party_repository_service: Arc<dyn ThirdPartyRepositoryService>,
    integration_service: Arc<dyn IntegrationService>,
    repository_service: Arc<dyn RepositoryService>,
    context_service: Arc<dyn ContextService>,
    license_service: Arc<dyn LicenseService>,
    notification_service: Arc<dyn NotificationService>,
    embedding: Arc<dyn Embedding>,
) {

Review comment (bug):
```suggestion
                r#"Job `{}` has failed.
```

Code after:
        BackgroundJobEvent::SchedulerGithubGitlabRepository(_) => "Indexing Repository",
        BackgroundJobEvent::SyncThirdPartyRepositories(_) => "Loading Repository",
        BackgroundJobEvent::WebCrawler(_) => "Web Indexing",
        BackgroundJobEvent::IndexGarbageCollection => "Garbage Collection",
        BackgroundJobEvent::Hourly => "Hourly",
        BackgroundJobEvent::Daily => "Daily",
    }
}

async fn notify_job_error(
    notification_service: Arc<dyn NotificationService>,
    err: &str,
    event: &BackgroundJobEvent,
    id: i64,
) {
    warn!("job {:?} failed: {:?}", event, err);
    let name = background_job_notification_name(event);
    if let Err(err) = notification_service
        .create(
            NotificationRecipient::Admin,
            &format!(
                r#"Job **{}** has failed.

Please examine the [logs](/jobs/detail?id={}) to determine the underlying issue.
"#,
                name,
                id.as_id()
            ),
        )
        .await
    {
        warn!("Failed to send notification: {:?}", err);
    }
}

pub async fn start(
    db: DbConn,
    job_service: Arc<dyn JobService>,
    git_repository_service: Arc<dyn GitRepositoryService>,
    third_party_repository_service: Arc<dyn ThirdPartyRepositoryService>,
    integration_service: Arc<dyn IntegrationService>,
    repository_service: Arc<dyn RepositoryService>,
    context_service: Arc<dyn ContextService>,
    license_service: Arc<dyn LicenseService>,
    notification_service: Arc<dyn NotificationService>,
    embedding: Arc<dyn Embedding>,
) {
    let mut hourly =
        CronStream::new(Schedule::from_str("@hourly").expect("Invalid cron expression"))
            .into_stream();