Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Catch and handle corrupted json files #399

Merged
merged 7 commits into from
May 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added
* Handle corrupted json files by @bleykauf in https://github.com/linien-org/linien/pull/399

## [2.0.2] - 2024-05-14

### Fixed
Expand Down
18 changes: 17 additions & 1 deletion linien-common/linien_common/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@
#
# You should have received a copy of the GNU General Public License
# along with Linien. If not, see <http://www.gnu.org/licenses/>.

import logging
from pathlib import Path

from appdirs import AppDirs

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

ACQUISITION_PORT = 19321
SERVER_PORT = 18862
DEFAULT_SWEEP_SPEED = (125 * 2048) << 6
Expand All @@ -29,3 +32,16 @@

LOG_FILE_PATH = USER_DATA_PATH / "linien.log"
LOG_FILE_PATH.parent.mkdir(parents=True, exist_ok=True)


def create_backup_file(filename: Path) -> None:
"""Rename the file to a unique filename."""
i = 0
while True:
backup_filename = filename.parent / f"{filename.stem}.backup{i}"
if not backup_filename.exists():
break
i += 1

filename.rename(backup_filename)
logger.info(f"{filename} has been saved as {backup_filename}.")
6 changes: 5 additions & 1 deletion linien-common/linien_common/influxdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import logging
from dataclasses import dataclass

from .config import USER_DATA_PATH
from .config import USER_DATA_PATH, create_backup_file

CREDENTIAL_STORE_FILENAME = "influxdb_credentials.json"

Expand Down Expand Up @@ -69,3 +69,7 @@ def restore_credentials() -> InfluxDBCredentials:
)
except FileNotFoundError:
return InfluxDBCredentials()
except json.JSONDecodeError:
logger.error(f"Credentials file {filename} was corrupted.")
create_backup_file(filename)
return InfluxDBCredentials()
13 changes: 8 additions & 5 deletions linien-gui/linien_gui/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@
from pathlib import Path
from typing import Callable, Iterator, Tuple

from linien_common.config import USER_DATA_PATH
from linien_common.config import USER_DATA_PATH, create_backup_file

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

UI_PATH = Path(__file__).parents[0].resolve() / "ui"

SETTINGS_STORE_FILENAME = "settings.json"
# don't plot more often than once per `DEFAULT_PLOT_RATE_LIMIT` seconds
DEFAULT_PLOT_RATE_LIMIT = 0.1

Expand Down Expand Up @@ -118,19 +118,22 @@ def __iter__(self) -> Iterator[Tuple[str, Setting]]:

def save_settings(settings: Settings) -> None:
data = {name: setting.value for name, setting in settings}
with open(USER_DATA_PATH / "settings.json", "w") as f:
with open(USER_DATA_PATH / SETTINGS_STORE_FILENAME, "w") as f:
json.dump(data, f, indent=0)


def load_settings() -> Settings:
settings = Settings()
filename = USER_DATA_PATH / SETTINGS_STORE_FILENAME
try:
with open(USER_DATA_PATH / "settings.json", "r") as f:
with open(filename, "r") as f:
data = json.load(f)
for name, value in data.items():
if name in settings.__dict__:
getattr(settings, name).value = value
except FileNotFoundError:
save_settings(settings)

except json.JSONDecodeError:
logger.error(f"Settings file {filename} was corrupted.")
create_backup_file(filename)
return settings
6 changes: 5 additions & 1 deletion linien-server/linien_server/parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

import linien_server
from linien_common.common import AutolockMode, MHz, PSDAlgorithm, Vpp
from linien_common.config import USER_DATA_PATH
from linien_common.config import USER_DATA_PATH, create_backup_file

PARAMETER_STORE_FILENAME = "parameters.json"

Expand Down Expand Up @@ -667,6 +667,10 @@ def restore_parameters(parameters: Parameters) -> Parameters:
except FileNotFoundError:
logger.info(f"Couldn't find {filename}. Using default parameters.")
return parameters
except json.JSONDecodeError:
logger.error(f"Parameters file {filename} was corrupted.")
create_backup_file(filename)
return parameters

for name, attributes in data["parameters"].items():
try:
Expand Down