]> source.dussan.org Git - tigervnc.git/commitdiff
Consistently use exceptions for parameter errors
authorPierre Ossman <ossman@cendio.se>
Wed, 8 Sep 2021 07:11:28 +0000 (09:11 +0200)
committerPierre Ossman <ossman@cendio.se>
Wed, 8 Sep 2021 08:36:17 +0000 (10:36 +0200)
Clean up the structure around storing and loading parameters and server
history so that failures will always be reported by using exceptions.

vncviewer/ServerDialog.cxx
vncviewer/parameters.cxx

index 4fbc0811ad20ea3a1fdd97e44f25ebf4eabb0df7..1c20dd309a1c5da952c810e877be23ef5db6e660 100644 (file)
@@ -36,6 +36,7 @@
 
 #include <os/os.h>
 #include <rfb/Exception.h>
+#include <rfb/LogWriter.h>
 
 #include "ServerDialog.h"
 #include "OptionsDialog.h"
@@ -48,6 +49,8 @@
 using namespace std;
 using namespace rfb;
 
+static LogWriter vlog("ServerDialog");
+
 const char* SERVER_HISTORY="tigervnc.history";
 
 ServerDialog::ServerDialog()
@@ -64,10 +67,6 @@ ServerDialog::ServerDialog()
   y = margin;
   
   serverName = new Fl_Input_Choice(x, y, w() - margin*2 - server_label_width, INPUT_HEIGHT, _("VNC server:"));
-  loadServerHistory();
-  for(size_t i=0;i<serverHistory.size();++i) {
-    serverName->add(serverHistory[i].c_str());
-  }
 
   int adjust = (w() - 20) / 4;
   int button_width = adjust - margin/2;
@@ -130,6 +129,21 @@ void ServerDialog::run(const char* servername, char *newservername)
   dialog.serverName->value(servername);
 
   dialog.show();
+
+  try {
+    size_t i;
+
+    dialog.loadServerHistory();
+
+    dialog.serverName->clear();
+    for(i = 0; i < dialog.serverHistory.size(); ++i)
+      dialog.serverName->add(dialog.serverHistory[i].c_str());
+  } catch (Exception& e) {
+    vlog.error("%s", e.str());
+    fl_alert(_("Unable to load the server history:\n\n%s"),
+             e.str());
+  }
+
   while (dialog.shown()) Fl::wait();
 
   if (dialog.serverName->value() == NULL) {
@@ -171,7 +185,9 @@ void ServerDialog::handleLoad(Fl_Widget *widget, void *data)
   try {
     dialog->serverName->value(loadViewerParameters(filename));
   } catch (Exception& e) {
-    fl_alert("%s", e.str());
+    vlog.error("%s", e.str());
+    fl_alert(_("Unable to load the specified configuration file:\n\n%s"),
+             e.str());
   }
 
   delete(file_chooser);
@@ -226,7 +242,9 @@ void ServerDialog::handleSaveAs(Fl_Widget *widget, void *data)
   try {
     saveViewerParameters(filename, servername);
   } catch (Exception& e) {
-    fl_alert("%s", e.str());
+    vlog.error("%s", e.str());
+    fl_alert(_("Unable to save the specified configuration "
+               "file:\n\n%s"), e.str());
   }
   
   delete(file_chooser);
@@ -257,7 +275,13 @@ void ServerDialog::handleConnect(Fl_Widget *widget, void *data)
 
   try {
     saveViewerParameters(NULL, servername);
+  } catch (Exception& e) {
+    vlog.error("%s", e.str());
+    fl_alert(_("Unable to save the default configuration:\n\n%s"),
+             e.str());
+  }
 
+  try {
     vector<string>::iterator elem = std::find(dialog->serverHistory.begin(), dialog->serverHistory.end(), servername);
     // avoid duplicates in the history
     if(dialog->serverHistory.end() == elem) {
@@ -265,13 +289,17 @@ void ServerDialog::handleConnect(Fl_Widget *widget, void *data)
       dialog->saveServerHistory();
     }
   } catch (Exception& e) {
-    fl_alert("%s", e.str());
+    vlog.error("%s", e.str());
+    fl_alert(_("Unable to save the server history:\n\n%s"),
+             e.str());
   }
 }
 
 
 void ServerDialog::loadServerHistory()
 {
+  serverHistory.clear();
+
 #ifdef _WIN32
   loadHistoryFromRegKey(serverHistory);
   return;
index 8db714ae25b818420e2f4f9542dda3f8bad10514..ab5d587267eeaf2fbaf2b7806236dd201594589b 100644 (file)
@@ -297,30 +297,21 @@ static void setKeyString(const char *_name, const char *_value, HKEY* hKey) {
 
   wchar_t name[buffersize];
   unsigned size = fl_utf8towc(_name, strlen(_name)+1, name, buffersize);
-  if (size >= buffersize) {
-    vlog.error(_("The name of the parameter %s was too large to write to the registry"), _name);
-    return;
-  }
+  if (size >= buffersize)
+    throw Exception(_("The name of the parameter is too large"));
 
   char encodingBuffer[buffersize];
-  if (!encodeValue(_value, encodingBuffer, buffersize)) {
-    vlog.error(_("The parameter %s was too large to write to the registry"), _name);
-    return;
-  }
+  if (!encodeValue(_value, encodingBuffer, buffersize))
+    throw Exception(_("The parameter is too large"));
 
   wchar_t value[buffersize];
   size = fl_utf8towc(encodingBuffer, strlen(encodingBuffer)+1, value, buffersize);
-  if (size >= buffersize) {
-    vlog.error(_("The parameter %s was too large to write to the registry"), _name);
-    return;
-  }
+  if (size >= buffersize)
+    throw Exception(_("The parameter is too large"));
 
   LONG res = RegSetValueExW(*hKey, name, 0, REG_SZ, (BYTE*)&value, (wcslen(value)+1)*2);
-  if (res != ERROR_SUCCESS) {
-    vlog.error(_("Failed to write parameter %s of type %s to the registry: %ld"),
-               _name, "REG_SZ", res);
-    return;
-  }
+  if (res != ERROR_SUCCESS)
+    throw rdr::SystemException("RegSetValueExW", res);
 }
 
 
@@ -331,17 +322,12 @@ static void setKeyInt(const char *_name, const int _value, HKEY* hKey) {
   DWORD value = _value;
 
   unsigned size = fl_utf8towc(_name, strlen(_name)+1, name, buffersize);
-  if (size >= buffersize) {
-    vlog.error(_("The name of the parameter %s was too large to write to the registry"), _name);
-    return;
-  }
-  
+  if (size >= buffersize)
+    throw Exception(_("The name of the parameter is too large"));
+
   LONG res = RegSetValueExW(*hKey, name, 0, REG_DWORD, (BYTE*)&value, sizeof(DWORD));
-  if (res != ERROR_SUCCESS) {
-    vlog.error(_("Failed to write parameter %s of type %s to the registry: %ld"),
-               _name, "REG_DWORD", res);
-    return;
-  }
+  if (res != ERROR_SUCCESS)
+    throw rdr::SystemException("RegSetValueExW", res);
 }
 
 
@@ -353,38 +339,35 @@ static bool getKeyString(const char* _name, char* dest, size_t destSize, HKEY* h
   DWORD valuesize;
 
   unsigned size = fl_utf8towc(_name, strlen(_name)+1, name, buffersize);
-  if (size >= buffersize) {
-    vlog.error(_("The name of the parameter %s was too large to read from the registry"), _name);
-    return false;
-  }
+  if (size >= buffersize)
+    throw Exception(_("The name of the parameter is too large"));
 
   value = new WCHAR[destSize];
   valuesize = destSize;
   LONG res = RegQueryValueExW(*hKey, name, 0, NULL, (LPBYTE)value, &valuesize);
   if (res != ERROR_SUCCESS){
     delete [] value;
-    if (res == ERROR_FILE_NOT_FOUND) {
-      // The value does not exist, defaults will be used.
-    } else {
-      vlog.error(_("Failed to read parameter %s from the registry: %ld"),
-                 _name, res);
-    }
+    if (res != ERROR_FILE_NOT_FOUND)
+      throw rdr::SystemException("RegQueryValueExW", res);
+    // The value does not exist, defaults will be used.
     return false;
   }
-  
+
   char* utf8val = new char[destSize];
   size = fl_utf8fromwc(utf8val, destSize, value, wcslen(value)+1);
   delete [] value;
   if (size >= destSize) {
     delete [] utf8val;
-    vlog.error(_("The parameter %s was too large to read from the registry"), _name);
-    return false;
+    throw Exception(_("The parameter is too large"));
   }
-  
+
   bool ret = decodeValue(utf8val, dest, destSize);
   delete [] utf8val;
 
-  return ret;
+  if (!ret)
+    throw Exception(_("Invalid format or too large value"));
+
+  return true;
 }
 
 
@@ -396,19 +379,14 @@ static bool getKeyInt(const char* _name, int* dest, HKEY* hKey) {
   wchar_t name[buffersize];
 
   unsigned size = fl_utf8towc(_name, strlen(_name)+1, name, buffersize);
-  if (size >= buffersize) {
-    vlog.error(_("The name of the parameter %s was too large to read from the registry"), _name);
-    return false;
-  }
+  if (size >= buffersize)
+    throw Exception(_("The name of the parameter is too large"));
 
   LONG res = RegQueryValueExW(*hKey, name, 0, NULL, (LPBYTE)&value, &dwordsize);
   if (res != ERROR_SUCCESS){
-    if (res == ERROR_FILE_NOT_FOUND) {
-      // The value does not exist, defaults will be used.
-    } else {
-      vlog.error(_("Failed to read parameter %s from the registry: %ld"),
-                 _name, res);
-    }
+    if (res != ERROR_FILE_NOT_FOUND)
+      throw rdr::SystemException("RegQueryValueExW", res);
+    // The value does not exist, defaults will be used.
     return false;
   }
 
@@ -416,29 +394,21 @@ static bool getKeyInt(const char* _name, int* dest, HKEY* hKey) {
   return true;
 }
 
-static bool removeValue(const char* _name, HKEY* hKey) {
+static void removeValue(const char* _name, HKEY* hKey) {
   const DWORD buffersize = 256;
   wchar_t name[buffersize];
 
   unsigned size = fl_utf8towc(_name, strlen(_name)+1, name, buffersize);
-  if (size >= buffersize) {
-    vlog.error(_("The name of the parameter %s was too large to remove from the registry"), _name);
-    return false;
-  }
+  if (size >= buffersize)
+    throw Exception(_("The name of the parameter is too large"));
 
   LONG res = RegDeleteValueW(*hKey, name);
   if (res != ERROR_SUCCESS) {
-    if (res == ERROR_FILE_NOT_FOUND) {
-      // The value does not exist, no need to remove it.
-      return true;
-    } else {
-      vlog.error(_("Failed to remove parameter %s from the registry: %ld"),
-                 _name, res);
-      return false;
-    }
+    if (res != ERROR_FILE_NOT_FOUND)
+      throw rdr::SystemException("RegDeleteValueW", res);
+    // The value does not exist, no need to remove it.
+    return;
   }
-
-  return true;
 }
 
 void saveHistoryToRegKey(const vector<string>& serverHistory) {
@@ -448,25 +418,27 @@ void saveHistoryToRegKey(const vector<string>& serverHistory) {
                              REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
                              &hKey, NULL);
 
-  if (res != ERROR_SUCCESS) {
-    vlog.error(_("Failed to create registry key: %ld"), res);
-    return;
-  }
+  if (res != ERROR_SUCCESS)
+    throw rdr::SystemException(_("Failed to create registry key"), res);
 
   size_t index = 0;
   assert(SERVER_HISTORY_SIZE < 100);
   char indexString[3];
 
-  while(index < serverHistory.size() && index <= SERVER_HISTORY_SIZE) {
-    snprintf(indexString, 3, "%d", index);
-    setKeyString(indexString, serverHistory[index].c_str(), &hKey);
-    index++;
+  try {
+    while(index < serverHistory.size() && index <= SERVER_HISTORY_SIZE) {
+      snprintf(indexString, 3, "%d", index);
+      setKeyString(indexString, serverHistory[index].c_str(), &hKey);
+      index++;
+    }
+  } catch (Exception& e) {
+    RegCloseKey(hKey);
+    throw;
   }
 
   res = RegCloseKey(hKey);
-  if (res != ERROR_SUCCESS) {
-    vlog.error(_("Failed to close registry key: %ld"), res);
-  }
+  if (res != ERROR_SUCCESS)
+    throw rdr::SystemException(_("Failed to close registry key"), res);
 }
 
 static void saveToReg(const char* servername) {
@@ -477,36 +449,51 @@ static void saveToReg(const char* servername) {
                              L"Software\\TigerVNC\\vncviewer", 0, NULL,
                              REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
                              &hKey, NULL);
-  if (res != ERROR_SUCCESS) {
-    vlog.error(_("Failed to create registry key: %ld"), res);
-    return;
-  }
+  if (res != ERROR_SUCCESS)
+    throw rdr::SystemException(_("Failed to create registry key"), res);
 
-  setKeyString("ServerName", servername, &hKey);
+  try {
+    setKeyString("ServerName", servername, &hKey);
+  } catch (Exception& e) {
+    RegCloseKey(hKey);
+    throw Exception(_("Failed to save \"%s\": %s"),
+                    "ServerName", e.str());
+  }
 
   for (size_t i = 0; i < sizeof(parameterArray)/sizeof(VoidParameter*); i++) {
-    if (dynamic_cast<StringParameter*>(parameterArray[i]) != NULL) {
-      setKeyString(parameterArray[i]->getName(), *(StringParameter*)parameterArray[i], &hKey);
-    } else if (dynamic_cast<IntParameter*>(parameterArray[i]) != NULL) {
-      setKeyInt(parameterArray[i]->getName(), (int)*(IntParameter*)parameterArray[i], &hKey);
-    } else if (dynamic_cast<BoolParameter*>(parameterArray[i]) != NULL) {
-      setKeyInt(parameterArray[i]->getName(), (int)*(BoolParameter*)parameterArray[i], &hKey);
-    } else {      
-      vlog.error(_("Unknown parameter type for parameter %s"),
-                 parameterArray[i]->getName());
+    try {
+      if (dynamic_cast<StringParameter*>(parameterArray[i]) != NULL) {
+        setKeyString(parameterArray[i]->getName(), *(StringParameter*)parameterArray[i], &hKey);
+      } else if (dynamic_cast<IntParameter*>(parameterArray[i]) != NULL) {
+        setKeyInt(parameterArray[i]->getName(), (int)*(IntParameter*)parameterArray[i], &hKey);
+      } else if (dynamic_cast<BoolParameter*>(parameterArray[i]) != NULL) {
+        setKeyInt(parameterArray[i]->getName(), (int)*(BoolParameter*)parameterArray[i], &hKey);
+      } else {
+        throw Exception(_("Unknown parameter type"));
+      }
+    } catch (Exception& e) {
+      RegCloseKey(hKey);
+      throw Exception(_("Failed to save \"%s\": %s"),
+                      parameterArray[i]->getName(), e.str());
     }
   }
 
   // Remove read-only parameters to replicate the behaviour of Linux/macOS when they
   // store a config to disk. If the parameter hasn't been migrated at this point it
   // will be lost.
-  for (size_t i = 0; i < sizeof(readOnlyParameterArray)/sizeof(VoidParameter*); i++)
-    removeValue(readOnlyParameterArray[i]->getName(), &hKey);
+  for (size_t i = 0; i < sizeof(readOnlyParameterArray)/sizeof(VoidParameter*); i++) {
+    try {
+      removeValue(readOnlyParameterArray[i]->getName(), &hKey);
+    } catch (Exception& e) {
+      RegCloseKey(hKey);
+      throw Exception(_("Failed to remove \"%s\": %s"),
+                      readOnlyParameterArray[i]->getName(), e.str());
+    }
+  }
 
   res = RegCloseKey(hKey);
-  if (res != ERROR_SUCCESS) {
-    vlog.error(_("Failed to close registry key: %ld"), res);
-  }
+  if (res != ERROR_SUCCESS)
+    throw rdr::SystemException(_("Failed to close registry key"), res);
 }
 
 void loadHistoryFromRegKey(vector<string>& serverHistory) {
@@ -518,54 +505,64 @@ void loadHistoryFromRegKey(vector<string>& serverHistory) {
   if (res != ERROR_SUCCESS) {
     if (res == ERROR_FILE_NOT_FOUND) {
       // The key does not exist, defaults will be used.
-    } else {
-      vlog.error(_("Failed to open registry key: %ld"), res);
+      return;
     }
-    return;
+
+    throw rdr::SystemException(_("Failed to open registry key"), res);
   }
 
-  bool stop = false;
-  size_t index = 0;
+  size_t index;
   const DWORD buffersize = 256;
   char indexString[3];
 
-  while(!stop) {
+  for (index = 0;;index++) {
     snprintf(indexString, 3, "%d", index);
     char servernameBuffer[buffersize];
-    if (getKeyString(indexString, servernameBuffer, buffersize, &hKey)) {
-      serverHistory.push_back(servernameBuffer);
-      index++;
-    }
-    else {
-      stop = true;
+
+    try {
+      if (!getKeyString(indexString, servernameBuffer,
+                        buffersize, &hKey))
+        break;
+    } catch (Exception& e) {
+      // Just ignore this entry and try the next one
+      vlog.error(_("Failed to read server history entry %d: %s"),
+                 (int)index, e.str());
+      continue;
     }
+
+    serverHistory.push_back(servernameBuffer);
   }
 
   res = RegCloseKey(hKey);
-  if (res != ERROR_SUCCESS){
-    vlog.error(_("Failed to close registry key: %ld"), res);
-  }
+  if (res != ERROR_SUCCESS)
+    throw rdr::SystemException(_("Failed to close registry key"), res);
 }
 
-static void findAndSetViewerParametersFromReg(VoidParameter* parameters[], size_t parameters_len, HKEY* hKey) {
-
+static void getParametersFromReg(VoidParameter* parameters[],
+                                 size_t parameters_len, HKEY* hKey)
+{
   const size_t buffersize = 256;
   int intValue = 0;
   char stringValue[buffersize];
 
   for (size_t i = 0; i < parameters_len/sizeof(VoidParameter*); i++) {
-    if (dynamic_cast<StringParameter*>(parameters[i]) != NULL) {
-      if (getKeyString(parameters[i]->getName(), stringValue, buffersize, hKey))
-        parameters[i]->setParam(stringValue);
-    } else if (dynamic_cast<IntParameter*>(parameters[i]) != NULL) {
-      if (getKeyInt(parameters[i]->getName(), &intValue, hKey))
-        ((IntParameter*)parameters[i])->setParam(intValue);
-    } else if (dynamic_cast<BoolParameter*>(parameters[i]) != NULL) {
-      if (getKeyInt(parameters[i]->getName(), &intValue, hKey))
-        ((BoolParameter*)parameters[i])->setParam(intValue);
-    } else {
-      vlog.error(_("Unknown parameter type for parameter %s"),
-                 parameters[i]->getName());
+    try {
+      if (dynamic_cast<StringParameter*>(parameters[i]) != NULL) {
+        if (getKeyString(parameters[i]->getName(), stringValue, buffersize, hKey))
+          parameters[i]->setParam(stringValue);
+      } else if (dynamic_cast<IntParameter*>(parameters[i]) != NULL) {
+        if (getKeyInt(parameters[i]->getName(), &intValue, hKey))
+          ((IntParameter*)parameters[i])->setParam(intValue);
+      } else if (dynamic_cast<BoolParameter*>(parameters[i]) != NULL) {
+        if (getKeyInt(parameters[i]->getName(), &intValue, hKey))
+          ((BoolParameter*)parameters[i])->setParam(intValue);
+      } else {
+        throw Exception(_("Unknown parameter type"));
+      }
+    } catch(Exception& e) {
+      // Just ignore this entry and continue with the rest
+      vlog.error(_("Failed to read parameter \"%s\": %s"),
+                 parameters[i]->getName(), e.str());
     }
   }
 }
@@ -580,27 +577,33 @@ static char* loadFromReg() {
   if (res != ERROR_SUCCESS) {
     if (res == ERROR_FILE_NOT_FOUND) {
       // The key does not exist, defaults will be used.
-    } else {
-      vlog.error(_("Failed to open registry key: %ld"), res);
+      return NULL;
     }
-    return NULL;
+
+    throw rdr::SystemException(_("Failed to open registry key"), res);
   }
 
   const size_t buffersize = 256;
   static char servername[buffersize];
 
   char servernameBuffer[buffersize];
-  if (getKeyString("ServerName", servernameBuffer, buffersize, &hKey))
-    snprintf(servername, buffersize, "%s", servernameBuffer);
-  
-  findAndSetViewerParametersFromReg(parameterArray, sizeof(parameterArray), &hKey);
-  findAndSetViewerParametersFromReg(readOnlyParameterArray, sizeof(readOnlyParameterArray), &hKey);
+  try {
+    if (getKeyString("ServerName", servernameBuffer, buffersize, &hKey))
+      snprintf(servername, buffersize, "%s", servernameBuffer);
+  } catch(Exception& e) {
+    vlog.error(_("Failed to read parameter \"%s\": %s"),
+               "ServerName", e.str());
+    strcpy(servername, "");
+  }
+
+  getParametersFromReg(parameterArray, sizeof(parameterArray), &hKey);
+  getParametersFromReg(readOnlyParameterArray,
+                       sizeof(readOnlyParameterArray), &hKey);
 
   res = RegCloseKey(hKey);
-  if (res != ERROR_SUCCESS){
-    vlog.error(_("Failed to close registry key: %ld"), res);
-  }
-  
+  if (res != ERROR_SUCCESS)
+    throw rdr::SystemException(_("Failed to close registry key"), res);
+
   return servername;
 }
 #endif // _WIN32
@@ -621,11 +624,8 @@ void saveViewerParameters(const char *filename, const char *servername) {
 #endif
     
     char* homeDir = NULL;
-    if (getvnchomedir(&homeDir) == -1) {
-      vlog.error(_("Failed to write configuration file, can't obtain home "
-                   "directory path."));
-      return;
-    }
+    if (getvnchomedir(&homeDir) == -1)
+      throw Exception(_("Could not obtain the home directory path"));
 
     snprintf(filepath, sizeof(filepath), "%sdefault.tigervnc", homeDir);
     delete[] homeDir;
@@ -642,20 +642,32 @@ void saveViewerParameters(const char *filename, const char *servername) {
   fprintf(f, "%s\n", IDENTIFIER_STRING);
   fprintf(f, "\n");
 
-  if (encodeValue(servername, encodingBuffer, buffersize))
-    fprintf(f, "ServerName=%s\n", encodingBuffer);
+  if (!encodeValue(servername, encodingBuffer, buffersize)) {
+    fclose(f);
+    throw Exception(_("Failed to save \"%s\": %s"),
+                    "ServerName", _("Could not encode parameter"));
+  }
+  fprintf(f, "ServerName=%s\n", encodingBuffer);
 
   for (size_t i = 0; i < sizeof(parameterArray)/sizeof(VoidParameter*); i++) {
     if (dynamic_cast<StringParameter*>(parameterArray[i]) != NULL) {
-      if (encodeValue(*(StringParameter*)parameterArray[i], encodingBuffer, buffersize))
-        fprintf(f, "%s=%s\n", ((StringParameter*)parameterArray[i])->getName(), encodingBuffer);
+      if (!encodeValue(*(StringParameter*)parameterArray[i],
+          encodingBuffer, buffersize)) {
+        fclose(f);
+        throw Exception(_("Failed to save \"%s\": %s"),
+                        parameterArray[i]->getName(),
+                        _("Could not encode parameter"));
+      }
+      fprintf(f, "%s=%s\n", ((StringParameter*)parameterArray[i])->getName(), encodingBuffer);
     } else if (dynamic_cast<IntParameter*>(parameterArray[i]) != NULL) {
       fprintf(f, "%s=%d\n", ((IntParameter*)parameterArray[i])->getName(), (int)*(IntParameter*)parameterArray[i]);
     } else if (dynamic_cast<BoolParameter*>(parameterArray[i]) != NULL) {
       fprintf(f, "%s=%d\n", ((BoolParameter*)parameterArray[i])->getName(), (int)*(BoolParameter*)parameterArray[i]);
     } else {      
-      vlog.error(_("Unknown parameter type for parameter %s"),
-                 parameterArray[i]->getName());
+      fclose(f);
+      throw Exception(_("Failed to save \"%s\": %s"),
+                      parameterArray[i]->getName(),
+                      _("Unknown parameter type"));
     }
   }
   fclose(f);
@@ -663,7 +675,7 @@ void saveViewerParameters(const char *filename, const char *servername) {
 
 static bool findAndSetViewerParameterFromValue(
   VoidParameter* parameters[], size_t parameters_len,
-  char* value, char* line, int lineNr, char* filepath)
+  char* value, char* line, char* filepath)
 {
   const size_t buffersize = 256;
   char decodingBuffer[buffersize];
@@ -673,12 +685,8 @@ static bool findAndSetViewerParameterFromValue(
 
     if (dynamic_cast<StringParameter*>(parameters[i]) != NULL) {
       if (strcasecmp(line, ((StringParameter*)parameters[i])->getName()) == 0) {
-
-        if(!decodeValue(value, decodingBuffer, sizeof(decodingBuffer))) {
-          vlog.error(_("Failed to read line %d in file %s: %s"),
-                      lineNr, filepath, _("Invalid format or too large value"));
-          continue;
-        }
+        if(!decodeValue(value, decodingBuffer, sizeof(decodingBuffer)))
+          throw Exception(_("Invalid format or too large value"));
         ((StringParameter*)parameters[i])->setParam(decodingBuffer);
         return false;
       }
@@ -696,8 +704,7 @@ static bool findAndSetViewerParameterFromValue(
       }
 
     } else {
-      vlog.error(_("Unknown parameter type for parameter %s"),
-                  parameters[i]->getName());
+      throw Exception(_("Unknown parameter type"));
     }
   }
 
@@ -750,21 +757,25 @@ char* loadViewerParameters(const char *filename) {
       if (feof(f))
         break;
 
+      fclose(f);
       throw Exception(_("Failed to read line %d in file %s: %s"),
                       lineNr, filepath, strerror(errno));
     }
 
-    if (strlen(line) == (sizeof(line) - 1))
+    if (strlen(line) == (sizeof(line) - 1)) {
+      fclose(f);
       throw Exception(_("Failed to read line %d in file %s: %s"),
                       lineNr, filepath, _("Line too long"));
-    
+    }
+
     // Make sure that the first line of the file has the file identifier string
     if(lineNr == 1) {
       if(strncmp(line, IDENTIFIER_STRING, strlen(IDENTIFIER_STRING)) == 0)
         continue;
-      else
-        throw Exception(_("Configuration file %s is in an invalid format"),
-                        filepath);
+
+      fclose(f);
+      throw Exception(_("Configuration file %s is in an invalid format"),
+                      filepath);
     }
     
     // Skip empty lines and comments
@@ -794,24 +805,28 @@ char* loadViewerParameters(const char *filename) {
     bool invalidParameterName = true; // Will be set to false below if 
                                       // the line contains a valid name.
 
-    if (strcasecmp(line, "ServerName") == 0) {
+    try {
+      if (strcasecmp(line, "ServerName") == 0) {
 
-      if(!decodeValue(value, decodingBuffer, sizeof(decodingBuffer))) {
-        vlog.error(_("Failed to read line %d in file %s: %s"),
-                   lineNr, filepath, _("Invalid format or too large value"));
-        continue;
-      }
-      snprintf(servername, sizeof(decodingBuffer), "%s", decodingBuffer);
-      invalidParameterName = false;
+        if(!decodeValue(value, decodingBuffer, sizeof(decodingBuffer)))
+          throw Exception(_("Invalid format or too large value"));
+        snprintf(servername, sizeof(decodingBuffer), "%s", decodingBuffer);
+        invalidParameterName = false;
 
-    } else {
-      invalidParameterName = findAndSetViewerParameterFromValue(parameterArray, sizeof(parameterArray),
-                                                                value, line, lineNr, filepath);
+      } else {
+        invalidParameterName = findAndSetViewerParameterFromValue(parameterArray, sizeof(parameterArray),
+                                                                  value, line, filepath);
 
-      if (invalidParameterName) {
-        invalidParameterName = findAndSetViewerParameterFromValue(readOnlyParameterArray, sizeof(readOnlyParameterArray),
-                                                                  value, line, lineNr, filepath);
+        if (invalidParameterName) {
+          invalidParameterName = findAndSetViewerParameterFromValue(readOnlyParameterArray, sizeof(readOnlyParameterArray),
+                                                                    value, line, filepath);
+        }
       }
+    } catch(Exception& e) {
+      // Just ignore this entry and continue with the rest
+      vlog.error(_("Failed to read line %d in file %s: %s"),
+                 lineNr, filepath, e.str());
+      continue;
     }
 
     if (invalidParameterName)