Show errors on failure (#5643)
Co-authored-by: Douwe Osinga <douwe@squareup.com>
This commit is contained in:
@@ -17,6 +17,7 @@ use thiserror::Error;
|
||||
|
||||
const KEYRING_SERVICE: &str = "goose";
|
||||
const KEYRING_USERNAME: &str = "secrets";
|
||||
pub const CONFIG_YAML_NAME: &str = "config.yaml";
|
||||
|
||||
#[cfg(test)]
|
||||
const TEST_KEYRING_SERVICE: &str = "goose-test";
|
||||
@@ -119,9 +120,7 @@ impl Default for Config {
|
||||
fn default() -> Self {
|
||||
let config_dir = Paths::config_dir();
|
||||
|
||||
std::fs::create_dir_all(&config_dir).expect("Failed to create config directory");
|
||||
|
||||
let config_path = config_dir.join("config.yaml");
|
||||
let config_path = config_dir.join(CONFIG_YAML_NAME);
|
||||
|
||||
let secrets = match env::var("GOOSE_DISABLE_KEYRING") {
|
||||
Ok(_) => SecretStorage::File {
|
||||
@@ -433,7 +432,6 @@ impl Config {
|
||||
// Convert to YAML for storage
|
||||
let yaml_value = serde_yaml::to_string(&values)?;
|
||||
|
||||
// Ensure the directory exists
|
||||
if let Some(parent) = self.config_path.parent() {
|
||||
std::fs::create_dir_all(parent)
|
||||
.map_err(|e| ConfigError::DirectoryError(e.to_string()))?;
|
||||
|
||||
@@ -24,7 +24,8 @@ pub fn prepare_log_directory(component: &str, use_date_subdir: bool) -> Result<P
|
||||
component_dir
|
||||
};
|
||||
|
||||
fs::create_dir_all(&log_dir).context("Failed to create log directory")?;
|
||||
fs::create_dir_all(&log_dir)
|
||||
.with_context(|| format!("Failed to create log directory: {:?}", log_dir))?;
|
||||
|
||||
Ok(log_dir)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use anyhow::Result;
|
||||
use anyhow::{anyhow, Result};
|
||||
use reqwest::Client;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
@@ -166,7 +166,6 @@ impl PricingCache {
|
||||
|
||||
self.save_to_disk(&cached_data).await?;
|
||||
|
||||
// Update memory cache
|
||||
{
|
||||
let mut cache = self.memory_cache.write().await;
|
||||
*cache = Some(cached_data);
|
||||
@@ -179,15 +178,6 @@ impl PricingCache {
|
||||
pub async fn initialize(&self) -> Result<()> {
|
||||
// Try loading from disk first
|
||||
if let Ok(Some(cached)) = self.load_from_disk().await {
|
||||
// Log how many models we have cached
|
||||
let total_models: usize = cached.pricing.values().map(|models| models.len()).sum();
|
||||
tracing::debug!(
|
||||
"Loaded {} providers with {} total models from disk cache",
|
||||
cached.pricing.len(),
|
||||
total_models
|
||||
);
|
||||
|
||||
// Update memory cache
|
||||
{
|
||||
let mut cache = self.memory_cache.write().await;
|
||||
*cache = Some(cached);
|
||||
@@ -196,8 +186,6 @@ impl PricingCache {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// If no disk cache, fetch from OpenRouter
|
||||
tracing::info!("Fetching pricing data from OpenRouter API");
|
||||
self.refresh().await
|
||||
}
|
||||
}
|
||||
@@ -213,14 +201,13 @@ lazy_static::lazy_static! {
|
||||
static ref PRICING_CACHE: PricingCache = PricingCache::new();
|
||||
}
|
||||
|
||||
/// Create a properly configured HTTP client for the current runtime
|
||||
fn create_http_client() -> Client {
|
||||
fn create_http_client() -> Result<Client> {
|
||||
Client::builder()
|
||||
.timeout(Duration::from_secs(30))
|
||||
.pool_idle_timeout(Duration::from_secs(90))
|
||||
.pool_max_idle_per_host(10)
|
||||
.build()
|
||||
.expect("Failed to create HTTP client")
|
||||
.map_err(|e| anyhow!(e))
|
||||
}
|
||||
|
||||
/// OpenRouter model pricing information
|
||||
@@ -254,7 +241,7 @@ pub struct OpenRouterModelsResponse {
|
||||
|
||||
/// Internal function to fetch pricing data
|
||||
async fn fetch_openrouter_pricing_internal() -> Result<HashMap<String, OpenRouterModel>> {
|
||||
let client = create_http_client();
|
||||
let client = create_http_client()?;
|
||||
let response = client
|
||||
.get("https://openrouter.ai/api/v1/models")
|
||||
.send()
|
||||
|
||||
@@ -190,13 +190,6 @@ impl Scheduler {
|
||||
|
||||
let local_tz = Local::now().timezone();
|
||||
|
||||
tracing::info!(
|
||||
"Creating cron task for job '{}' cron: '{}' in timezone: {:?}",
|
||||
job.id,
|
||||
cron,
|
||||
local_tz
|
||||
);
|
||||
|
||||
Job::new_async_tz(&cron, local_tz, move |_uuid, _l| {
|
||||
tracing::info!("Cron task triggered for job '{}'", job_for_task.id);
|
||||
let task_job_id = job_for_task.id.clone();
|
||||
@@ -215,7 +208,6 @@ impl Scheduler {
|
||||
};
|
||||
|
||||
if !should_execute {
|
||||
tracing::info!("Skipping paused job '{}'", task_job_id);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -731,15 +723,11 @@ async fn execute_job(
|
||||
}
|
||||
}
|
||||
|
||||
if let Err(e) = SessionManager::update_session(&session.id)
|
||||
SessionManager::update_session(&session.id)
|
||||
.schedule_id(Some(job.id.clone()))
|
||||
.recipe(Some(recipe))
|
||||
.apply()
|
||||
.await
|
||||
{
|
||||
tracing::error!("Failed to update session: {}", e);
|
||||
}
|
||||
|
||||
.await?;
|
||||
Ok(session.id)
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@ use tracing::{info, warn};
|
||||
use utoipa::ToSchema;
|
||||
|
||||
const CURRENT_SCHEMA_VERSION: i32 = 5;
|
||||
pub const SESSIONS_FOLDER: &str = "sessions";
|
||||
pub const DB_NAME: &str = "sessions.db";
|
||||
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize, ToSchema, PartialEq, Eq)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
@@ -335,7 +337,7 @@ pub struct SessionStorage {
|
||||
}
|
||||
|
||||
pub fn ensure_session_dir() -> Result<PathBuf> {
|
||||
let session_dir = Paths::data_dir().join("sessions");
|
||||
let session_dir = Paths::data_dir().join(SESSIONS_FOLDER);
|
||||
|
||||
if !session_dir.exists() {
|
||||
fs::create_dir_all(&session_dir)?;
|
||||
@@ -439,7 +441,7 @@ impl sqlx::FromRow<'_, sqlx::sqlite::SqliteRow> for Session {
|
||||
impl SessionStorage {
|
||||
async fn new() -> Result<Self> {
|
||||
let session_dir = ensure_session_dir()?;
|
||||
let db_path = session_dir.join("sessions.db");
|
||||
let db_path = session_dir.join(DB_NAME);
|
||||
|
||||
let storage = if db_path.exists() {
|
||||
Self::open(&db_path).await?
|
||||
|
||||
@@ -34,7 +34,6 @@ impl Default for OtlpConfig {
|
||||
|
||||
impl OtlpConfig {
|
||||
pub fn from_config() -> Option<Self> {
|
||||
// Try to get from goose config system (which checks env vars first, then config file)
|
||||
let config = crate::config::Config::global();
|
||||
|
||||
// Try to get the endpoint from config (checks OTEL_EXPORTER_OTLP_ENDPOINT env var first)
|
||||
|
||||
Reference in New Issue
Block a user