Commits

Christian Specht committed c3b8e07

improve exception handling, add custom exception for everything to be displayed to the client
(fixes #4)

Comments (0)

Files changed (7)

src/BitbucketBackup/BitbucketBackup.csproj

   </ItemGroup>
   <ItemGroup>
     <Compile Include="BitbucketRequest.cs" />
+    <Compile Include="ClientException.cs" />
     <Compile Include="Config.cs" />
     <Compile Include="Program.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />

src/BitbucketBackup/BitbucketRequest.cs

         /// </summary>
         private string credentials;
 
+        private Config config;
+
         /// <summary>
         /// Creates a new Bitbucket API request.
         /// </summary>
         {
             this.baseuri = new Uri("https://api.bitbucket.org/1.0/");
             this.credentials = Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(config.UserName + ":" + config.PassWord));
+            this.config = config;
         }
 
         /// <summary>
             var request = WebRequest.Create(uri.ToString()) as HttpWebRequest;
             request.Headers.Add("Authorization", "Basic " + this.credentials);
 
-            using (var response = request.GetResponse() as HttpWebResponse)
+            try
             {
-                var reader = new StreamReader(response.GetResponseStream());
-                return reader.ReadToEnd();
+                using (var response = request.GetResponse() as HttpWebResponse)
+                {
+                    var reader = new StreamReader(response.GetResponseStream());
+                    return reader.ReadToEnd();
+                }
+            }
+            catch (WebException ex)
+            {
+                using (HttpWebResponse resp = (HttpWebResponse)ex.Response)
+                {
+                    if (resp.StatusCode == HttpStatusCode.NotFound)
+                    {
+                        // if the Uri returns a 404, the username probably doesn't exist
+                        // (there could be other reasons, but this one is the most likely)
+                        throw new ClientException(string.Format(Resources.InvalidUsername, config.UserName), ex);
+                    }
+                    else
+                    {
+                        throw;
+                    }
+                }
             }
         }
     }

src/BitbucketBackup/ClientException.cs

+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace BitbucketBackup
+{
+    /// <summary>
+    /// custom exception, message will always be displayed to the user
+    /// </summary>
+    internal class ClientException : Exception
+    {
+        /// <summary>
+        /// Creates a new instance of the ClientException class.
+        /// </summary>
+        /// <param name="message">The error message</param>
+        /// <param name="innerException">The inner exception or null</param>
+        public ClientException(string message, Exception innerException)
+            : base(message, innerException)
+        {
+        }
+    }
+}

src/BitbucketBackup/Program.cs

         {
             int sleepTime = 2000;
 
-            var config = new Config();
-            var request = new BitbucketRequest(config);
+            try
+            {
+                var config = new Config();
+                var request = new BitbucketRequest(config);
 
-            string resource = "users/" + config.UserName;
-            string response = request.Execute(resource);
+                string resource = "users/" + config.UserName;
+                string response = request.Execute(resource);
 
-            if (response == string.Empty)
+                if (response == string.Empty)
+                {
+                    Console.WriteLine(Resources.NoResponse, resource);
+                    Console.ReadLine();
+                    return;
+                }
+
+                Console.WriteLine(Resources.IntroHeadline);
+                Console.WriteLine();
+                Console.WriteLine(Resources.IntroUser, config.UserName);
+                Console.WriteLine(Resources.IntroFolder, config.BackupFolder);
+                Console.WriteLine();
+                Thread.Sleep(sleepTime);
+
+                var json = JObject.Parse(response);
+                var repos =
+                    from r in json["repositories"].Children()
+                    select new { RepoName = (string)r["slug"], HasWiki = (bool)r["has_wiki"] };
+
+                var baseUri = new Uri("https://bitbucket.org/" + config.UserName + "/");
+
+                foreach (var repo in repos)
+                {
+                    var repoUri = new Uri(baseUri, repo.RepoName);
+                    string repoPath = Path.Combine(config.BackupFolder, repo.RepoName);
+
+                    var updater = new RepositoryUpdater(repoUri, repoPath, config);
+                    updater.Update();
+
+                    if (repo.HasWiki)
+                    {
+                        var wikiUri = new Uri(baseUri, repo.RepoName + "/wiki");
+                        string wikiPath = Path.Combine(config.BackupFolder, repo.RepoName + "-wiki");
+
+                        var wikiUpdater = new RepositoryUpdater(wikiUri, wikiPath, config);
+                        wikiUpdater.Update();
+                    }
+                }
+
+                Console.WriteLine();
+                Console.WriteLine(Resources.BackupCompleted);
+            }
+            catch (ClientException ex)
             {
-                Console.WriteLine(Resources.NoResponse, resource);
-                Console.ReadLine();
-                return;
+                Console.WriteLine(Resources.ClientExceptionHeadline);
+                Console.WriteLine(ex.Message);
             }
-
-            Console.WriteLine(Resources.IntroHeadline);
-            Console.WriteLine();
-            Console.WriteLine(Resources.IntroUser, config.UserName);
-            Console.WriteLine(Resources.IntroFolder, config.BackupFolder);
-            Console.WriteLine();
-            Thread.Sleep(sleepTime);
-
-            var json = JObject.Parse(response);
-            var repos =
-                from r in json["repositories"].Children()
-                select new { RepoName = (string)r["slug"], HasWiki = (bool)r["has_wiki"] };
-
-            var baseUri = new Uri("https://bitbucket.org/" + config.UserName + "/");
-
-            foreach (var repo in repos)
+            finally
             {
-                var repoUri = new Uri(baseUri, repo.RepoName);
-                string repoPath = Path.Combine(config.BackupFolder, repo.RepoName);                
-
-                var updater = new RepositoryUpdater(repoUri, repoPath, config);
-                updater.Update();
-
-                if (repo.HasWiki)
-                {
-                    var wikiUri = new Uri(baseUri, repo.RepoName + "/wiki");
-                    string wikiPath = Path.Combine(config.BackupFolder, repo.RepoName + "-wiki");
-
-                    var wikiUpdater = new RepositoryUpdater(wikiUri, wikiPath, config);
-                    wikiUpdater.Update();
-                }
+                Thread.Sleep(sleepTime);
             }
-
-            Console.WriteLine();
-            Console.WriteLine(Resources.BackupCompleted);
-            Thread.Sleep(sleepTime);
         }
     }
 }

src/BitbucketBackup/Resources.Designer.cs

         }
         
         /// <summary>
+        ///   Sucht eine lokalisierte Zeichenfolge, die Backup failed! ähnelt.
+        /// </summary>
+        internal static string ClientExceptionHeadline {
+            get {
+                return ResourceManager.GetString("ClientExceptionHeadline", resourceCulture);
+            }
+        }
+        
+        /// <summary>
         ///   Sucht eine lokalisierte Zeichenfolge, die Local backup folder: {0} ähnelt.
         /// </summary>
         internal static string IntroFolder {
         }
         
         /// <summary>
+        ///   Sucht eine lokalisierte Zeichenfolge, die Couldn&apos;t load information for user: {0}
+        ///Please check if the user name is valid! ähnelt.
+        /// </summary>
+        internal static string InvalidUsername {
+            get {
+                return ResourceManager.GetString("InvalidUsername", resourceCulture);
+            }
+        }
+        
+        /// <summary>
         ///   Sucht eine lokalisierte Zeichenfolge, die Bitbucket API didn&apos;t return a response: {0} ähnelt.
         /// </summary>
         internal static string NoResponse {

src/BitbucketBackup/Resources.de.resx

   <data name="BackupCompleted" xml:space="preserve">
     <value>Backup wurde abgeschlossen!</value>
   </data>
+  <data name="ClientExceptionHeadline" xml:space="preserve">
+    <value>Backup fehlgeschlagen!</value>
+  </data>
   <data name="IntroFolder" xml:space="preserve">
     <value>Lokaler Backup-Ordner: {0}</value>
   </data>
   <data name="IntroUser" xml:space="preserve">
     <value>Bitbucket-Benutzer: {0}</value>
   </data>
+  <data name="InvalidUsername" xml:space="preserve">
+    <value>Benutzerinfo konnte nicht geladen werden: {0}
+Bitte überprüfen Sie den Benutzernamen!</value>
+  </data>
   <data name="NoResponse" xml:space="preserve">
     <value>Die Bitbucket-API hat keine Antwort zurückgegeben: {0}</value>
   </data>

src/BitbucketBackup/Resources.resx

   <data name="Pulling" xml:space="preserve">
     <value>Pulling: {0}</value>
   </data>
+  <data name="ClientExceptionHeadline" xml:space="preserve">
+    <value>Backup failed!</value>
+  </data>
+  <data name="InvalidUsername" xml:space="preserve">
+    <value>Couldn't load information for user: {0}
+Please check if the user name is valid!</value>
+  </data>
 </root>