diff --git a/cache.go b/cache.go index a6cb51a..f4e6ad1 100644 --- a/cache.go +++ b/cache.go @@ -12,9 +12,9 @@ import ( // Cache represents a token cacher. type Cache interface { // Read reads a cache token from the specified file. - Read() (token *Token, err error) + Read() (token *Token) // Write writes a token to the specified file. - Write(token *Token) (err error) + Write(token *Token) } // NewFileCache creates a new file cache. @@ -24,25 +24,29 @@ func NewFileCache(filename string) *FileCache { // FileCache represents a file based token cacher. type FileCache struct { - filename string + filename string + ErrorHandlerFunc func(error) } // Read reads a cache token from the specified file. -func (f *FileCache) Read() (token *Token, err error) { +func (f *FileCache) Read() (token *Token) { data, err := ioutil.ReadFile(f.filename) - if err != nil { - return nil, err + if err == nil { + err = json.Unmarshal(data, token) } - token = &Token{} - err = json.Unmarshal(data, &token) - return token, err + if f.ErrorHandlerFunc != nil { + f.ErrorHandlerFunc(err) + } + return } // Write writes a token to the specified file. -func (f *FileCache) Write(token *Token) error { +func (f *FileCache) Write(token *Token) { data, err := json.Marshal(token) - if err != nil { - return err + if err == nil { + err = ioutil.WriteFile(f.filename, data, 0644) + } + if f.ErrorHandlerFunc != nil { + f.ErrorHandlerFunc(err) } - return ioutil.WriteFile(f.filename, data, 0644) } diff --git a/cache_test.go b/cache_test.go new file mode 100644 index 0000000..a7bfef1 --- /dev/null +++ b/cache_test.go @@ -0,0 +1,27 @@ +// Copyright 2014 The oauth2 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package oauth2 + +import ( + "os" + "testing" +) + +func TestFileCacheErrorHandling(t *testing.T) { + var lastErr error + fileCache := NewFileCache("/path/that/doesnt/exist") + fileCache.ErrorHandlerFunc = func(err error) { + lastErr = err + } + fileCache.Read() + if !os.IsNotExist(lastErr) { + t.Fatalf("Read should have invoked the error handling func with os.ErrNotExist, but read err is %v", lastErr) + } + lastErr = nil + fileCache.Write(&Token{}) + if !os.IsNotExist(lastErr) { + t.Fatalf("Write should have invoked the error handling func with os.ErrNotExist, but read err is %v", lastErr) + } +} diff --git a/oauth2.go b/oauth2.go index 9d005d3..8a6e39f 100644 --- a/oauth2.go +++ b/oauth2.go @@ -64,6 +64,7 @@ type TokenFetcher interface { // If the implementation doesn't know how to retrieve a new token, // it returns an error. FetchToken(existing *Token) (*Token, error) + // Cache returns the Cache implementation to read/persist user tokens. Cache() Cache } diff --git a/transport.go b/transport.go index 3fe8167..dac1707 100644 --- a/transport.go +++ b/transport.go @@ -98,7 +98,7 @@ func (t *authorizedTransport) RoundTrip(req *http.Request) (resp *http.Response, if token == nil && cache != nil { // Try to read from cache initially - token, _ := cache.Read() + token = cache.Read() } if token == nil || token.Expired() { // Check if the token is refreshable.