Skip to content

Commit 2b59add

Browse files
authored
fix: panic when fetching app metadata on Windows (#538)
* fix: panic when fetching app metadata on Windows * release note
1 parent ee75062 commit 2b59add

5 files changed

Lines changed: 42 additions & 26 deletions

File tree

docs/content.en/docs/release-notes/_index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ Information about release notes of Coco Server is provided here.
3434
- fix: loading chat history for potential empty attachments
3535
- fix: datasource & MCP list synchronization update #521
3636
- fix: show only enabled datasource & MCP list
37+
- fix: panic when fetching app metadata on Windows #538
3738

3839
### ✈️ Improvements
3940

src-tauri/src/local/application/mod.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ pub use with_feature::*;
1212
#[cfg(not(feature = "use_pizza_engine"))]
1313
pub use without_feature::*;
1414

15-
1615
#[derive(Debug, Serialize, Clone)]
1716
#[serde(rename_all = "camelCase")]
1817
pub struct AppEntry {
@@ -24,15 +23,13 @@ pub struct AppEntry {
2423
is_disabled: bool,
2524
}
2625

27-
2826
#[derive(serde::Serialize)]
2927
#[serde(rename_all = "camelCase")]
3028
pub struct AppMetadata {
3129
name: String,
3230
r#where: String,
3331
size: u64,
34-
icon: String,
3532
created: u128,
3633
modified: u128,
3734
last_opened: u128,
38-
}
35+
}

src-tauri/src/local/application/with_feature.rs

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,10 @@ fn get_app_path(app: &App) -> String {
117117

118118
/// Helper function to return `app`'s path.
119119
///
120-
/// * Windows/macOS: extract `app_path`'s file name and remove the file extension
121-
/// * Linux: return the name specified in `.desktop` file
120+
/// * macOS: extract `app_path`'s file name and remove the file extension
121+
/// * Windows/Linux: return the name specified in `.desktop` file
122122
async fn get_app_name(app: &App) -> String {
123-
if cfg!(target_os = "linux") {
123+
if cfg!(any(target_os = "linux", target_os = "windows")) {
124124
app.name.clone()
125125
} else {
126126
let app_path = get_app_path(app);
@@ -1074,15 +1074,7 @@ pub async fn get_app_list<R: Runtime>(
10741074
}
10751075

10761076
#[tauri::command]
1077-
pub async fn get_app_metadata<R: Runtime>(
1078-
tauri_app_handle: AppHandle<R>,
1079-
app_path: String,
1080-
) -> Result<AppMetadata, String> {
1081-
let app =
1082-
App::from_path(std::path::Path::new(&app_path)).expect("frontend sends an invalid app");
1083-
1084-
let app_path = get_app_path(&app);
1085-
let app_name = get_app_name(&app).await;
1077+
pub async fn get_app_metadata(app_name: String, app_path: String) -> Result<AppMetadata, String> {
10861078
let app_path_where = {
10871079
let app_path_borrowed_path = std::path::Path::new(app_path.as_str());
10881080
let app_path_where = app_path_borrowed_path
@@ -1094,11 +1086,13 @@ pub async fn get_app_metadata<R: Runtime>(
10941086
.expect("it is guaranteed to be UTF-8 encoded")
10951087
.to_string()
10961088
};
1097-
let icon = get_app_icon_path(&tauri_app_handle, &app).await?;
10981089

1099-
let raw_app_metadata = metadata(app_path.into(), None).await?;
1090+
let raw_app_metadata = metadata(app_path.clone().into(), None).await?;
1091+
1092+
let last_opened = if cfg!(target_os = "macos") {
1093+
let app = App::from_path(std::path::Path::new(&app_path))
1094+
.unwrap_or_else(|e| panic!("App::from_path({}) failed due to error '{}'", app_path, e));
11001095

1101-
let last_opened = if cfg!(any(target_os = "macos", target_os = "windows")) {
11021096
let app_exe_path = app
11031097
.app_path_exe
11041098
.as_ref()
@@ -1114,7 +1108,6 @@ pub async fn get_app_metadata<R: Runtime>(
11141108
name: app_name,
11151109
r#where: app_path_where,
11161110
size: raw_app_metadata.size,
1117-
icon,
11181111
created: raw_app_metadata.created_at,
11191112
modified: raw_app_metadata.modified_at,
11201113
last_opened,

src/components/Settings/Extensions/components/Details/Application/index.tsx

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,34 +4,59 @@ import dayjs from "dayjs";
44
import { useTranslation } from "react-i18next";
55
import { useAsyncEffect } from "ahooks";
66
import platformAdapter from "@/utils/platformAdapter";
7-
import { ExtensionsContext } from "../../..";
7+
import { ExtensionsContext, Plugin, type ExtensionsContextType } from "../../../index";
88

99
interface Metadata {
1010
name: string;
1111
where: string;
1212
size: number;
13-
icon: string;
1413
created: number;
1514
modified: number;
1615
lastOpened: number;
1716
}
1817

1918
const App = () => {
2019
const { t } = useTranslation();
21-
const { activeId } = useContext(ExtensionsContext);
20+
const { activeId, plugins } = useContext(ExtensionsContext) as ExtensionsContextType;
2221

2322
const [appMetadata, setAppMetadata] = useState<Metadata>();
2423

24+
const findPlugin = (plugins: Plugin[], id: string) => {
25+
for (const plugin of plugins) {
26+
const { children = [] } = plugin;
27+
28+
if (plugin.id === id) {
29+
return plugin;
30+
}
31+
32+
if (children.length > 0) {
33+
const matched = findPlugin(children, id) as Plugin;
34+
35+
if (!matched) continue;
36+
37+
return matched;
38+
}
39+
}
40+
};
41+
42+
const currentPlugin = useMemo(() => {
43+
if (!activeId) return;
44+
return findPlugin(plugins, activeId);
45+
}, [activeId, plugins]);
46+
2547
useAsyncEffect(async () => {
48+
if (!activeId || !currentPlugin) return;
49+
2650
const appMetadata = await platformAdapter.invokeBackend<Metadata>(
2751
"get_app_metadata",
2852
{
29-
appPath: activeId,
53+
appName: currentPlugin.name,
54+
appPath: activeId
3055
}
3156
);
3257

3358
setAppMetadata(appMetadata);
34-
}, [activeId]);
59+
}, [activeId, currentPlugin]);
3560

3661
const metadata = useMemo(() => {
3762
if (!appMetadata) return [];

src/components/Settings/Extensions/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export interface Plugin {
4545
onEnabledChange?: (enabled: boolean) => void;
4646
}
4747

48-
interface ExtensionsContextType {
48+
export interface ExtensionsContextType {
4949
plugins: Plugin[];
5050
setPlugins: Dispatch<SetStateAction<Plugin[]>>;
5151
activeId?: string;

0 commit comments

Comments
 (0)