a*.go: Handling unhandled errors

This commit is contained in:
Samuel Marks 2019-08-18 12:21:42 +10:00
parent dbb03fe989
commit 97019b11bd
No known key found for this signature in database
GPG key ID: A66D5F029DBB680C
25 changed files with 190 additions and 54 deletions

View file

@ -212,7 +212,9 @@ func (ac *accountCache) maybeReload() {
ac.watcher.start() ac.watcher.start()
ac.throttle.Reset(minReloadInterval) ac.throttle.Reset(minReloadInterval)
ac.mu.Unlock() ac.mu.Unlock()
ac.scanAccounts() if err := ac.scanAccounts(); err != nil {
// ignore error
}
} }
func (ac *accountCache) close() { func (ac *accountCache) close() {
@ -253,7 +255,11 @@ func (ac *accountCache) scanAccounts() error {
log.Trace("Failed to open keystore file", "path", path, "err", err) log.Trace("Failed to open keystore file", "path", path, "err", err)
return nil return nil
} }
defer fd.Close() defer func() {
if err := fd.Close(); err != nil {
panic(err)
}
}()
buf.Reset(fd) buf.Reset(fd)
// Parse the address. // Parse the address.
key.Address = "" key.Address = ""

View file

@ -55,7 +55,11 @@ func TestWatchNewFile(t *testing.T) {
t.Parallel() t.Parallel()
dir, ks := tmpKeyStore(t, false) dir, ks := tmpKeyStore(t, false)
defer os.RemoveAll(dir) defer func() {
if err := os.RemoveAll(dir); err != nil {
panic(err)
}
}()
// Ensure the watcher is started before adding any files. // Ensure the watcher is started before adding any files.
ks.Accounts() ks.Accounts()
@ -106,8 +110,14 @@ func TestWatchNoDir(t *testing.T) {
time.Sleep(100 * time.Millisecond) time.Sleep(100 * time.Millisecond)
// Create the directory and copy a key file into it. // Create the directory and copy a key file into it.
os.MkdirAll(dir, 0700) if err := os.MkdirAll(dir, 0700); err != nil {
defer os.RemoveAll(dir) panic(err)
}
defer func() {
if err := os.RemoveAll(dir); err != nil {
panic(err)
}
}()
file := filepath.Join(dir, "aaa") file := filepath.Join(dir, "aaa")
if err := cp.CopyFile(file, cachetestAccounts[0].URL.Path); err != nil { if err := cp.CopyFile(file, cachetestAccounts[0].URL.Path); err != nil {
t.Fatal(err) t.Fatal(err)
@ -332,8 +342,14 @@ func TestUpdatedKeyfileContents(t *testing.T) {
time.Sleep(100 * time.Millisecond) time.Sleep(100 * time.Millisecond)
// Create the directory and copy a key file into it. // Create the directory and copy a key file into it.
os.MkdirAll(dir, 0700) if err := os.MkdirAll(dir, 0700); err != nil {
defer os.RemoveAll(dir) panic(err)
}
defer func() {
if err := os.RemoveAll(dir); err != nil {
panic(err)
}
}()
file := filepath.Join(dir, "aaa") file := filepath.Join(dir, "aaa")
// Place one of our testfiles in there // Place one of our testfiles in there

View file

@ -111,8 +111,12 @@ func makeHasher(h hash.Hash) hasher {
outputLen := rh.Size() outputLen := rh.Size()
return func(dest []byte, data []byte) { return func(dest []byte, data []byte) {
rh.Reset() rh.Reset()
rh.Write(data) if _, err := rh.Write(data); err != nil {
rh.Read(dest[:outputLen]) // ignore error
}
if _, err := rh.Read(dest[:outputLen]); err != nil {
// ignore error
}
} }
} }

View file

@ -702,7 +702,11 @@ func TestConcurrentDiskCacheGeneration(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("Failed to create temporary cache dir: %v", err) t.Fatalf("Failed to create temporary cache dir: %v", err)
} }
defer os.RemoveAll(cachedir) defer func() {
if err := os.RemoveAll(cachedir); err != nil {
panic(err)
}
}()
// Define a heavy enough block, one from mainnet should do // Define a heavy enough block, one from mainnet should do
block := types.NewBlockWithHeader(&types.Header{ block := types.NewBlockWithHeader(&types.Header{
@ -730,7 +734,11 @@ func TestConcurrentDiskCacheGeneration(t *testing.T) {
go func(idx int) { go func(idx int) {
defer pend.Done() defer pend.Done()
ethash := New(Config{cachedir, 0, 1, "", 0, 0, ModeNormal}, nil, false) ethash := New(Config{cachedir, 0, 1, "", 0, 0, ModeNormal}, nil, false)
defer ethash.Close() defer func() {
if err := ethash.Close(); err != nil {
panic(err)
}
}()
if err := ethash.VerifySeal(nil, block.Header()); err != nil { if err := ethash.VerifySeal(nil, block.Header()); err != nil {
t.Errorf("proc %d: block verification failed: %v", idx, err) t.Errorf("proc %d: block verification failed: %v", idx, err)
} }

View file

@ -71,7 +71,9 @@ func TestBodyStorage(t *testing.T) {
body := &types.Body{Uncles: []*types.Header{{Extra: []byte("test header")}}} body := &types.Body{Uncles: []*types.Header{{Extra: []byte("test header")}}}
hasher := sha3.NewLegacyKeccak256() hasher := sha3.NewLegacyKeccak256()
rlp.Encode(hasher, body) if err := rlp.Encode(hasher, body); err != nil {
t.Fatalf("rlp.Encode failed with %v on %v", hasher, body)
}
hash := common.BytesToHash(hasher.Sum(nil)) hash := common.BytesToHash(hasher.Sum(nil))
if entry := ReadBody(db, hash, 0); entry != nil { if entry := ReadBody(db, hash, 0); entry != nil {

View file

@ -64,8 +64,8 @@ func WriteTxLookupEntries(db ethdb.KeyValueWriter, block *types.Block) {
} }
// DeleteTxLookupEntry removes all transaction data associated with a hash. // DeleteTxLookupEntry removes all transaction data associated with a hash.
func DeleteTxLookupEntry(db ethdb.KeyValueWriter, hash common.Hash) { func DeleteTxLookupEntry(db ethdb.KeyValueWriter, hash common.Hash) error {
db.Delete(txLookupKey(hash)) return db.Delete(txLookupKey(hash))
} }
// ReadTransaction retrieves a specific transaction from the database, along with // ReadTransaction retrieves a specific transaction from the database, along with

View file

@ -56,7 +56,9 @@ func TestLookupStorage(t *testing.T) {
Index: uint64(index), Index: uint64(index),
} }
data, _ := rlp.EncodeToBytes(entry) data, _ := rlp.EncodeToBytes(entry)
db.Put(txLookupKey(tx.Hash()), data) if err := db.Put(txLookupKey(tx.Hash()), data); err != nil {
// ignore error
}
} }
}, },
}, },

View file

@ -173,12 +173,20 @@ func (api *PrivateAdminAPI) ExportChain(file string) (bool, error) {
if err != nil { if err != nil {
return false, err return false, err
} }
defer out.Close() defer func() {
if err := out.Close(); err != nil {
panic(err)
}
}()
var writer io.Writer = out var writer io.Writer = out
if strings.HasSuffix(file, ".gz") { if strings.HasSuffix(file, ".gz") {
writer = gzip.NewWriter(writer) writer = gzip.NewWriter(writer)
defer writer.(*gzip.Writer).Close() defer func() {
if err := writer.(*gzip.Writer).Close(); err != nil {
panic(err)
}
}()
} }
// Export the blockchain // Export the blockchain
@ -205,7 +213,11 @@ func (api *PrivateAdminAPI) ImportChain(file string) (bool, error) {
if err != nil { if err != nil {
return false, err return false, err
} }
defer in.Close() defer func() {
if err := in.Close(); err != nil {
panic(err)
}
}()
var reader io.Reader = in var reader io.Reader = in
if strings.HasSuffix(file, ".gz") { if strings.HasSuffix(file, ".gz") {

View file

@ -56,7 +56,9 @@ func (b *EthAPIBackend) CurrentBlock() *types.Block {
func (b *EthAPIBackend) SetHead(number uint64) { func (b *EthAPIBackend) SetHead(number uint64) {
b.eth.protocolManager.downloader.Cancel() b.eth.protocolManager.downloader.Cancel()
b.eth.blockchain.SetHead(number) if err := b.eth.blockchain.SetHead(number); err != nil {
panic(err)
}
} }
func (b *EthAPIBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) { func (b *EthAPIBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) {

View file

@ -81,7 +81,9 @@ func TestAccountRange(t *testing.T) {
} }
} }
state.Commit(true) if _, err := state.Commit(true); err != nil {
panic(err)
}
root := state.IntermediateRoot(true) root := state.IntermediateRoot(true)
trie, err := statedb.OpenTrie(root) trie, err := statedb.OpenTrie(root)
@ -165,7 +167,9 @@ func TestEmptyAccountRange(t *testing.T) {
state, _ = state.New(common.Hash{}, statedb) state, _ = state.New(common.Hash{}, statedb)
) )
state.Commit(true) if _, err := state.Commit(true); err != nil {
panic(err)
}
root := state.IntermediateRoot(true) root := state.IntermediateRoot(true)
trie, err := statedb.OpenTrie(root) trie, err := statedb.OpenTrie(root)

View file

@ -340,7 +340,9 @@ func (api *PrivateDebugAPI) traceChain(ctx context.Context, start, end *types.Bl
// Stream completed traces to the user, aborting on the first error // Stream completed traces to the user, aborting on the first error
for result, ok := done[next]; ok; result, ok = done[next] { for result, ok := done[next]; ok; result, ok = done[next] {
if len(result.Traces) > 0 || next == end.NumberU64() { if len(result.Traces) > 0 || next == end.NumberU64() {
notifier.Notify(sub.ID, result) if err := notifier.Notify(sub.ID, result); err != nil {
panic(err)
}
} }
delete(done, next) delete(done, next)
next++ next++
@ -598,10 +600,15 @@ func (api *PrivateDebugAPI) standardTraceBlockToFile(ctx context.Context, block
vmenv := vm.NewEVM(vmctx, statedb, api.eth.blockchain.Config(), vmConf) vmenv := vm.NewEVM(vmctx, statedb, api.eth.blockchain.Config(), vmConf)
_, _, _, err = core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas())) _, _, _, err = core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()))
if writer != nil { if writer != nil {
writer.Flush() if err := writer.Flush(); err != nil {
panic(err)
}
} }
if dump != nil { if dump != nil {
dump.Close() if er := dump.Close(); er != nil {
log.Error("Previous error", err)
panic(er)
}
log.Info("Wrote standard trace", "file", dump.Name()) log.Info("Wrote standard trace", "file", dump.Name())
} }
if err != nil { if err != nil {

View file

@ -105,7 +105,9 @@ func (api *PublicDownloaderAPI) Syncing(ctx context.Context) (*rpc.Subscription,
for { for {
select { select {
case status := <-statuses: case status := <-statuses:
notifier.Notify(rpcSub.ID, status) if err := notifier.Notify(rpcSub.ID, status); err != nil {
panic(err)
}
case <-rpcSub.Err(): case <-rpcSub.Err():
sub.Unsubscribe() sub.Unsubscribe()
return return

View file

@ -153,7 +153,9 @@ func (api *PublicFilterAPI) NewPendingTransactions(ctx context.Context) (*rpc.Su
// To keep the original behaviour, send a single tx hash in one notification. // To keep the original behaviour, send a single tx hash in one notification.
// TODO(rjl493456442) Send a batch of tx hashes in one notification // TODO(rjl493456442) Send a batch of tx hashes in one notification
for _, h := range hashes { for _, h := range hashes {
notifier.Notify(rpcSub.ID, h) if err := notifier.Notify(rpcSub.ID, h); err != nil {
panic(err)
}
} }
case <-rpcSub.Err(): case <-rpcSub.Err():
pendingTxSub.Unsubscribe() pendingTxSub.Unsubscribe()
@ -219,7 +221,9 @@ func (api *PublicFilterAPI) NewHeads(ctx context.Context) (*rpc.Subscription, er
for { for {
select { select {
case h := <-headers: case h := <-headers:
notifier.Notify(rpcSub.ID, h) if err := notifier.Notify(rpcSub.ID, h); err != nil {
panic(err)
}
case <-rpcSub.Err(): case <-rpcSub.Err():
headersSub.Unsubscribe() headersSub.Unsubscribe()
return return
@ -256,7 +260,9 @@ func (api *PublicFilterAPI) Logs(ctx context.Context, crit FilterCriteria) (*rpc
select { select {
case logs := <-matchedLogs: case logs := <-matchedLogs:
for _, log := range logs { for _, log := range logs {
notifier.Notify(rpcSub.ID, &log) if err := notifier.Notify(rpcSub.ID, &log); err != nil {
panic(err)
}
} }
case <-rpcSub.Err(): // client send an unsubscribe request case <-rpcSub.Err(): // client send an unsubscribe request
logsSub.Unsubscribe() logsSub.Unsubscribe()

View file

@ -58,7 +58,11 @@ func AddFile(a Archive, file string) error {
if err != nil { if err != nil {
return err return err
} }
defer fd.Close() defer func () {
if err := fd.Close(); err != nil {
panic(err)
}
}()
fi, err := fd.Stat() fi, err := fd.Stat()
if err != nil { if err != nil {
return err return err
@ -81,10 +85,14 @@ func WriteArchive(name string, files []string) (err error) {
} }
defer func() { defer func() {
archfd.Close() if er := archfd.Close(); er != nil {
panic(er)
}
// Remove the half-written archive on failure. // Remove the half-written archive on failure.
if err != nil { if err != nil {
os.Remove(name) if e := os.Remove(name); e != nil {
// Ignore error
}
} }
}() }()
archive, basename := NewArchive(archfd) archive, basename := NewArchive(archfd)

View file

@ -63,7 +63,11 @@ func AzureBlobstoreUpload(path string, name string, config AzureBlobstoreConfig)
if err != nil { if err != nil {
return err return err
} }
defer in.Close() defer func () {
if err := in.Close(); err != nil {
panic(err)
}
}()
_, err = blockblob.Upload(context.Background(), in, azblob.BlobHTTPHeaders{}, azblob.Metadata{}, azblob.BlobAccessConditions{}) _, err = blockblob.Upload(context.Background(), in, azblob.BlobHTTPHeaders{}, azblob.Metadata{}, azblob.BlobAccessConditions{})
return err return err

View file

@ -90,7 +90,9 @@ func (h *HandlerT) CpuProfile(file string, nsec uint) error {
return err return err
} }
time.Sleep(time.Duration(nsec) * time.Second) time.Sleep(time.Duration(nsec) * time.Second)
h.StopCPUProfile() if err := h.StopCPUProfile(); err != nil {
panic(err)
}
return nil return nil
} }
@ -106,7 +108,10 @@ func (h *HandlerT) StartCPUProfile(file string) error {
return err return err
} }
if err := pprof.StartCPUProfile(f); err != nil { if err := pprof.StartCPUProfile(f); err != nil {
f.Close() if er := f.Close(); er != nil {
log.Error("Overridden error", err)
return er
}
return err return err
} }
h.cpuW = f h.cpuW = f
@ -124,7 +129,9 @@ func (h *HandlerT) StopCPUProfile() error {
return errors.New("CPU profiling not in progress") return errors.New("CPU profiling not in progress")
} }
log.Info("Done writing CPU profile", "dump", h.cpuFile) log.Info("Done writing CPU profile", "dump", h.cpuFile)
h.cpuW.Close() if err := h.cpuW.Close(); err != nil {
panic(err)
}
h.cpuW = nil h.cpuW = nil
h.cpuFile = "" h.cpuFile = ""
return nil return nil
@ -137,7 +144,9 @@ func (h *HandlerT) GoTrace(file string, nsec uint) error {
return err return err
} }
time.Sleep(time.Duration(nsec) * time.Second) time.Sleep(time.Duration(nsec) * time.Second)
h.StopGoTrace() if err := h.StopGoTrace(); err != nil {
return err
}
return nil return nil
} }
@ -192,7 +201,9 @@ func (*HandlerT) WriteMemProfile(file string) error {
// Stacks returns a printed representation of the stacks of all goroutines. // Stacks returns a printed representation of the stacks of all goroutines.
func (*HandlerT) Stacks() string { func (*HandlerT) Stacks() string {
buf := new(bytes.Buffer) buf := new(bytes.Buffer)
pprof.Lookup("goroutine").WriteTo(buf, 2) if err := pprof.Lookup("goroutine").WriteTo(buf, 2); err != nil {
panic(err)
}
return buf.String() return buf.String()
} }
@ -214,7 +225,11 @@ func writeProfile(name, file string) error {
if err != nil { if err != nil {
return err return err
} }
defer f.Close() defer func () {
if err := f.Close(); err != nil {
panic(err)
}
}()
return p.WriteTo(f, 0) return p.WriteTo(f, 0)
} }

View file

@ -55,7 +55,9 @@ func (b *LesApiBackend) CurrentBlock() *types.Block {
func (b *LesApiBackend) SetHead(number uint64) { func (b *LesApiBackend) SetHead(number uint64) {
b.eth.protocolManager.downloader.Cancel() b.eth.protocolManager.downloader.Cancel()
b.eth.blockchain.SetHead(number) if err := b.eth.blockchain.SetHead(number); err != nil {
panic(err)
}
} }
func (b *LesApiBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) { func (b *LesApiBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) {

View file

@ -116,7 +116,9 @@ func testCapacityAPI(t *testing.T, clientCount int) {
if i != freeIdx { if i != freeIdx {
setCapacity(ctx, t, serverRpcClient, client.ID(), testCap/uint64(len(clients))) setCapacity(ctx, t, serverRpcClient, client.ID(), testCap/uint64(len(clients)))
} }
net.Connect(client.ID(), server.ID()) if err := net.Connect(client.ID(), server.ID()); err != nil {
panic(err)
}
for { for {
select { select {
@ -434,7 +436,11 @@ func NewAdapter(adapterType string, services adapters.Services) (adapter adapter
if err0 != nil { if err0 != nil {
return nil, teardown, err0 return nil, teardown, err0
} }
teardown = func() { os.RemoveAll(baseDir) } teardown = func() {
if err := os.RemoveAll(baseDir); err != nil {
panic(err)
}
}
adapter = adapters.NewExecAdapter(baseDir) adapter = adapters.NewExecAdapter(baseDir)
/*case "docker": /*case "docker":
adapter, err = adapters.NewDockerAdapter() adapter, err = adapters.NewDockerAdapter()

View file

@ -204,7 +204,9 @@ func (pool *TxPool) rollbackTxs(hash common.Hash, txc txStateChanges) {
if list, ok := pool.mined[hash]; ok { if list, ok := pool.mined[hash]; ok {
for _, tx := range list { for _, tx := range list {
txHash := tx.Hash() txHash := tx.Hash()
rawdb.DeleteTxLookupEntry(batch, txHash) if err := rawdb.DeleteTxLookupEntry(batch, txHash); err != nil {
// ignore err
}
pool.pending[txHash] = tx pool.pending[txHash] = tx
txc.setState(txHash, false) txc.setState(txHash, false)
} }

View file

@ -169,7 +169,9 @@ func TestAndroid(t *testing.T) {
if _, err := os.Stat(autopath); err != nil { if _, err := os.Stat(autopath); err != nil {
t.Skip("ANDROID_HOME environment var not set, skipping") t.Skip("ANDROID_HOME environment var not set, skipping")
} }
os.Setenv("ANDROID_HOME", autopath) if err := os.Setenv("ANDROID_HOME", autopath); err != nil {
panic(err)
}
} }
if _, err := exec.Command("which", "gomobile").CombinedOutput(); err != nil { if _, err := exec.Command("which", "gomobile").CombinedOutput(); err != nil {
t.Log("gomobile missing, installing it...") t.Log("gomobile missing, installing it...")
@ -188,7 +190,11 @@ func TestAndroid(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("failed to create temporary workspace: %v", err) t.Fatalf("failed to create temporary workspace: %v", err)
} }
defer os.RemoveAll(workspace) defer func() {
if err := os.RemoveAll(workspace); err != nil {
panic(err)
}
}()
pwd, err := os.Getwd() pwd, err := os.Getwd()
if err != nil { if err != nil {
@ -197,7 +203,11 @@ func TestAndroid(t *testing.T) {
if err := os.Chdir(workspace); err != nil { if err := os.Chdir(workspace); err != nil {
t.Fatalf("failed to switch to temporary workspace: %v", err) t.Fatalf("failed to switch to temporary workspace: %v", err)
} }
defer os.Chdir(pwd) defer func() {
if err := os.Chdir(pwd); err != nil {
panic(err)
}
}()
// Create the skeleton of the Android project // Create the skeleton of the Android project
for _, dir := range []string{"src/main", "src/androidTest/java/org/ethereum/gethtest", "libs"} { for _, dir := range []string{"src/main", "src/androidTest/java/org/ethereum/gethtest", "libs"} {

View file

@ -128,7 +128,9 @@ func (api *PrivateAdminAPI) PeerEvents(ctx context.Context) (*rpc.Subscription,
for { for {
select { select {
case event := <-events: case event := <-events:
notifier.Notify(rpcSub.ID, event) if err := notifier.Notify(rpcSub.ID, event); err != nil {
panic(err)
}
case <-sub.Err(): case <-sub.Err():
return return
case <-rpcSub.Err(): case <-rpcSub.Err():

View file

@ -362,7 +362,9 @@ func (api *SignerAPI) startUSBListener() {
} }
case accounts.WalletDropped: case accounts.WalletDropped:
log.Info("Old wallet dropped", "url", event.Wallet.URL()) log.Info("Old wallet dropped", "url", event.Wallet.URL())
event.Wallet.Close() if err := event.Wallet.Close(); err != nil {
panic(err)
}
} }
} }
}() }()

View file

@ -99,12 +99,16 @@ func (ui *headlessUi) ApproveNewAccount(request *core.NewAccountRequest) (core.N
func (ui *headlessUi) ShowError(message string) { func (ui *headlessUi) ShowError(message string) {
//stdout is used by communication //stdout is used by communication
fmt.Fprintln(os.Stderr, message) if err := fmt.Fprintln(os.Stderr, message); err != nil {
panic(err)
}
} }
func (ui *headlessUi) ShowInfo(message string) { func (ui *headlessUi) ShowInfo(message string) {
//stdout is used by communication //stdout is used by communication
fmt.Fprintln(os.Stderr, message) if err := fmt.Fprintln(os.Stderr, message); err != nil {
panic(err)
}
} }
func tmpDirName(t *testing.T) string { func tmpDirName(t *testing.T) string {
@ -286,7 +290,9 @@ func TestSignTx(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
parsedTx := &types.Transaction{} parsedTx := &types.Transaction{}
rlp.Decode(bytes.NewReader(res.Raw), parsedTx) if err := rlp.Decode(bytes.NewReader(res.Raw), parsedTx); err != nil {
panic(err)
}
//The tx should NOT be modified by the UI //The tx should NOT be modified by the UI
if parsedTx.Value().Cmp(tx.Value.ToInt()) != 0 { if parsedTx.Value().Cmp(tx.Value.ToInt()) != 0 {
@ -312,7 +318,9 @@ func TestSignTx(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
parsedTx2 := &types.Transaction{} parsedTx2 := &types.Transaction{}
rlp.Decode(bytes.NewReader(res.Raw), parsedTx2) if err := rlp.Decode(bytes.NewReader(res.Raw), parsedTx2); err != nil {
panic(err)
}
//The tx should be modified by the UI //The tx should be modified by the UI
if parsedTx2.Value().Cmp(tx.Value.ToInt()) != 0 { if parsedTx2.Value().Cmp(tx.Value.ToInt()) != 0 {

View file

@ -70,7 +70,9 @@ func TestFileStorage(t *testing.T) {
filename: fmt.Sprintf("%v/vault.json", d), filename: fmt.Sprintf("%v/vault.json", d),
key: []byte("AES256Key-32Characters1234567890"), key: []byte("AES256Key-32Characters1234567890"),
} }
stored.writeEncryptedStorage(a) if err := stored.writeEncryptedStorage(a); err != nil {
// ignore error
}
read := &AESEncryptedStorage{ read := &AESEncryptedStorage{
filename: fmt.Sprintf("%v/vault.json", d), filename: fmt.Sprintf("%v/vault.json", d),
key: []byte("AES256Key-32Characters1234567890"), key: []byte("AES256Key-32Characters1234567890"),

View file

@ -418,10 +418,14 @@ func (api *PublicWhisperAPI) Messages(ctx context.Context, crit Criteria) (*rpc.
} }
} }
case <-rpcSub.Err(): case <-rpcSub.Err():
api.w.Unsubscribe(id) if err := api.w.Unsubscribe(id); err != nil {
panic(err)
}
return return
case <-notifier.Closed(): case <-notifier.Closed():
api.w.Unsubscribe(id) if err := api.w.Unsubscribe(id); err != nil {
panic(err)
}
return return
} }
} }