diff --git a/src-tauri/src/cmds.rs b/src-tauri/src/cmds.rs
index 4cd15e7923ca43355996564e3e338abf63b5cb71..01cf8708f370e154f3f8b1c59e1cec1db47003df 100644
--- a/src-tauri/src/cmds.rs
+++ b/src-tauri/src/cmds.rs
@@ -34,13 +34,9 @@ pub async fn import_profile(
   with_proxy: bool,
   profiles_state: State<'_, ProfilesState>,
 ) -> Result<(), String> {
-  match fetch_profile(&url, with_proxy).await {
-    Some(result) => {
-      let mut profiles = profiles_state.0.lock().unwrap();
-      profiles.import_from_url(url, result)
-    }
-    None => Err(format!("failed to fetch profile from `{}`", url)),
-  }
+  let result = fetch_profile(&url, with_proxy).await?;
+  let mut profiles = profiles_state.0.lock().unwrap();
+  profiles.import_from_url(url, result)
 }
 
 /// new a profile
@@ -82,23 +78,22 @@ pub async fn update_profile(
     Err(_) => return Err("failed to get profiles lock".into()),
   };
 
-  match fetch_profile(&url, with_proxy).await {
-    Some(result) => match profiles_state.0.lock() {
-      Ok(mut profiles) => {
-        profiles.update_item(index, result)?;
-
-        // reactivate the profile
-        let current = profiles.current.clone().unwrap_or(0);
-        if current == index {
-          let clash = clash_state.0.lock().unwrap();
-          profiles.activate(&clash)
-        } else {
-          Ok(())
-        }
+  let result = fetch_profile(&url, with_proxy).await?;
+
+  match profiles_state.0.lock() {
+    Ok(mut profiles) => {
+      profiles.update_item(index, result)?;
+
+      // reactivate the profile
+      let current = profiles.current.clone().unwrap_or(0);
+      if current == index {
+        let clash = clash_state.0.lock().unwrap();
+        profiles.activate(&clash)
+      } else {
+        Ok(())
       }
-      Err(_) => Err("failed to get profiles lock".into()),
-    },
-    None => Err(format!("failed to fetch profile from `{}`", url)),
+    }
+    Err(_) => Err("failed to get profiles lock".into()),
   }
 }
 
diff --git a/src-tauri/src/core/profiles.rs b/src-tauri/src/core/profiles.rs
index 1f7f055fd4d330a3c57b40007bdf696b676b06e8..e81b8925ca678d1aac26a006441b4422b5bfa1ab 100644
--- a/src-tauri/src/core/profiles.rs
+++ b/src-tauri/src/core/profiles.rs
@@ -60,7 +60,7 @@ pub struct ProfileResponse {
   pub name: String,
   pub file: String,
   pub data: String,
-  pub extra: ProfileExtra,
+  pub extra: Option<ProfileExtra>,
 }
 
 static PROFILE_YAML: &str = "profiles.yaml";
@@ -117,7 +117,7 @@ impl Profiles {
       mode: Some(format!("rule")),
       url: Some(url),
       selected: Some(vec![]),
-      extra: Some(result.extra),
+      extra: result.extra,
       updated: Some(now as usize),
     });
 
@@ -194,7 +194,7 @@ impl Profiles {
     File::create(file_path).unwrap().write(file_data).unwrap();
 
     items[index].name = Some(result.name);
-    items[index].extra = Some(result.extra);
+    items[index].extra = result.extra;
     items[index].updated = Some(now);
 
     self.items = Some(items);
diff --git a/src-tauri/src/utils/fetch.rs b/src-tauri/src/utils/fetch.rs
index a4031ef6a20efff68acb50ae8529eedab947742d..e0d50f415f36f02d420ddb40cb9fbf3674785634 100644
--- a/src-tauri/src/utils/fetch.rs
+++ b/src-tauri/src/utils/fetch.rs
@@ -22,36 +22,35 @@ fn parse_string<T: FromStr>(target: &str, key: &str) -> Option<T> {
   }
 }
 
-/// fetch and parse the profile
-pub async fn fetch_profile(url: &str, with_proxy: bool) -> Option<ProfileResponse> {
+/// fetch and parse the profile url
+/// maybe it contains some Subscription infomations, maybe not
+pub async fn fetch_profile(url: &str, with_proxy: bool) -> Result<ProfileResponse, String> {
   let builder = reqwest::ClientBuilder::new();
   let client = match with_proxy {
     true => builder.build(),
     false => builder.no_proxy().build(),
   };
-  let resp = match client {
-    Ok(client) => match client.get(url).send().await {
-      Ok(res) => res,
-      Err(_) => return None,
-    },
-    Err(_) => return None,
+
+  let resp = match client.unwrap().get(url).send().await {
+    Ok(res) => res,
+    Err(_) => return Err("failed to create https client".into()),
   };
 
   let header = resp.headers();
 
   // parse the Subscription Userinfo
-  let extra = {
-    let sub_info = match header.get("Subscription-Userinfo") {
-      Some(value) => value.to_str().unwrap_or(""),
-      None => "",
-    };
+  let extra = match header.get("Subscription-Userinfo") {
+    Some(value) => {
+      let sub_info = value.to_str().unwrap_or("");
 
-    ProfileExtra {
-      upload: parse_string(sub_info, "upload=").unwrap_or(0),
-      download: parse_string(sub_info, "download=").unwrap_or(0),
-      total: parse_string(sub_info, "total=").unwrap_or(0),
-      expire: parse_string(sub_info, "expire=").unwrap_or(0),
+      Some(ProfileExtra {
+        upload: parse_string(sub_info, "upload=").unwrap_or(0),
+        download: parse_string(sub_info, "download=").unwrap_or(0),
+        total: parse_string(sub_info, "total=").unwrap_or(0),
+        expire: parse_string(sub_info, "expire=").unwrap_or(0),
+      })
     }
+    None => None,
   };
 
   let file = {
@@ -71,17 +70,15 @@ pub async fn fetch_profile(url: &str, with_proxy: bool) -> Option<ProfileRespons
   };
 
   // get the data
-  let data = match resp.text_with_charset("utf-8").await {
-    Ok(d) => d,
-    Err(_) => return None,
-  };
-
-  Some(ProfileResponse {
-    file,
-    name,
-    data,
-    extra,
-  })
+  match resp.text_with_charset("utf-8").await {
+    Ok(data) => Ok(ProfileResponse {
+      file,
+      name,
+      data,
+      extra,
+    }),
+    Err(_) => Err("failed to parse the response data".into()),
+  }
 }
 
 #[test]