~edwargix/tallyard

d4ff726a2721bd49e3f5c2c4726ebd995c7c6d79 — David Florness 2 years ago c968789
Print helpful error message when the map schema is incompatible
2 files changed, 29 insertions(+), 6 deletions(-)

M cmd/tallyard/main.go
M election/map.go
M cmd/tallyard/main.go => cmd/tallyard/main.go +23 -2
@@ 2,6 2,7 @@ package main

import (
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"io/ioutil"


@@ 63,7 64,27 @@ func main() {

	// setup the elections store
	electionsMap, err := getElections(authInfo.UserID)
	if err != nil {
	if errors.Is(err, election.SchemaVersionError) {
		log.Error(err)
		fmt.Println("We couldn't load this device's stored elections because the current")
		fmt.Println("schema version is incompatible with your current tallyard's schema.")
		fmt.Println()
		fmt.Println("The only currently-supported ways to solve this are to either")
		fmt.Println()
		fmt.Println("1. delete your saved elections file to start from scratch.  Node that this")
		fmt.Println("   will remove your personal records of any of your concluded/in-progress")
		fmt.Println("   elections!!")
		fmt.Println()
		fmt.Printf ("    rm %s/tallyard/elections.json\n", xdg.DataHome())
		fmt.Println("    tallyard")
		fmt.Println()
		fmt.Println("2. downgrade tallyard to a previous version that supports your election")
		fmt.Println("   schema.  This is usually the version right before your current")
		fmt.Printf ("   version (%s) if you just upgraded and things were working beforehand.\n", tallyard.Version)
		fmt.Println("   Please feel free to join the #tallyard:hnitbjorg.xyz matrix for help")
		fmt.Println("   with this.")
		os.Exit(1)
	} else if err != nil {
		log.Panic(err)
	}
	client.Store = matrix.NewTallyardStore(electionsMap)


@@ 235,7 256,7 @@ func getElections(userID id.UserID) (*election.ElectionsMap, error) {
	log.Info("unmarshalling elections file...")
	em, err := election.UnmarshalElectionsMapFrom(jsonBytes, userID, saveElections)
	if err != nil {
		return nil, fmt.Errorf("couldn't read elections map: %s", err)
		return nil, fmt.Errorf("couldn't read elections map: %w", err)
	}

	return em, nil

M election/map.go => election/map.go +6 -4
@@ 2,6 2,7 @@ package election

import (
	"encoding/json"
	"errors"
	"fmt"
	"sync"



@@ 41,16 42,17 @@ func NewElectionsMap(userID id.UserID, save func(*ElectionsMap)) *ElectionsMap {
	}
}

var SchemaVersionError error = errors.New("the stored elections schema version is incompitable with the latest schema version")

func UnmarshalElectionsMapFrom(jsonBytes []byte, userID id.UserID, save func(*ElectionsMap)) (*ElectionsMap, error) {
	em := &ElectionsMap{}
	err := json.Unmarshal(jsonBytes, em)
	if em.Version != electionsMapVersion {
		return nil, SchemaVersionError
	}
	if err != nil {
		return nil, fmt.Errorf("error unmarshalling elections: %s", err)
	}
	if em.Version != electionsMapVersion {
		return nil, fmt.Errorf("Your stored elections schema version (%d) is incompitable with the latest schema version (%d).",
			em.Version, electionsMapVersion)
	}
	if userID != em.UserID {
		// TODO support multiple users?
		return nil, fmt.Errorf("user IDs don't match")