@@ -32,6 +32,8 @@ import software.aws.toolkits.core.utils.touch
3232import software.aws.toolkits.core.utils.tryDirOp
3333import software.aws.toolkits.core.utils.tryFileOp
3434import software.aws.toolkits.core.utils.tryOrNull
35+ import software.aws.toolkits.telemetry.AuthTelemetry
36+ import software.aws.toolkits.telemetry.Result
3537import java.io.InputStream
3638import java.io.OutputStream
3739import java.nio.file.Path
@@ -101,7 +103,18 @@ class DiskCache(
101103 override fun loadClientRegistration (cacheKey : ClientRegistrationCacheKey ): ClientRegistration ? {
102104 LOG .debug { " loadClientRegistration for $cacheKey " }
103105 val inputStream = clientRegistrationCache(cacheKey).tryInputStreamIfExists()
104- ? : return null
106+ if (inputStream == null ) {
107+ val stage = LoadCredentialStage .ACCESS_FILE
108+ LOG .warn(" Failed to load Client Registration: cache file does not exist" )
109+ AuthTelemetry .modifyConnection(
110+ action = " Load cache file" ,
111+ source = " loadClientRegistration" ,
112+ result = Result .Failed ,
113+ reason = " Failed to load Client Registration" ,
114+ reasonDesc = " Load Step:$stage failed. Unable to load file"
115+ )
116+ return null
117+ }
105118 return loadClientRegistration(inputStream)
106119 }
107120
@@ -115,12 +128,34 @@ class DiskCache(
115128
116129 override fun invalidateClientRegistration (cacheKey : ClientRegistrationCacheKey ) {
117130 LOG .debug { " invalidateClientRegistration for $cacheKey " }
118- clientRegistrationCache(cacheKey).tryDeleteIfExists()
131+ try {
132+ clientRegistrationCache(cacheKey).tryDeleteIfExists()
133+ } catch (e: Exception ) {
134+ AuthTelemetry .modifyConnection(
135+ action = " Delete cache file" ,
136+ source = " invalidateClientRegistration" ,
137+ result = Result .Failed ,
138+ reason = " Failed to invalidate Client Registration" ,
139+ reasonDesc = e.message ? : e::class .java.name
140+ )
141+ throw e
142+ }
119143 }
120144
121145 override fun invalidateAccessToken (ssoUrl : String ) {
122146 LOG .debug { " invalidateAccessToken for $ssoUrl " }
123- accessTokenCache(ssoUrl).tryDeleteIfExists()
147+ try {
148+ accessTokenCache(ssoUrl).tryDeleteIfExists()
149+ } catch (e: Exception ) {
150+ AuthTelemetry .modifyConnection(
151+ action = " Delete cache file" ,
152+ source = " invalidateAccessToken" ,
153+ result = Result .Failed ,
154+ reason = " Failed to invalidate Access Token" ,
155+ reasonDesc = e.message ? : e::class .java.name
156+ )
157+ throw e
158+ }
124159 }
125160
126161 override fun loadAccessToken (cacheKey : AccessTokenCacheKey ): AccessToken ? {
@@ -143,7 +178,18 @@ class DiskCache(
143178
144179 override fun invalidateAccessToken (cacheKey : AccessTokenCacheKey ) {
145180 LOG .debug { " invalidateAccessToken for $cacheKey " }
146- accessTokenCache(cacheKey).tryDeleteIfExists()
181+ try {
182+ accessTokenCache(cacheKey).tryDeleteIfExists()
183+ } catch (e: Exception ) {
184+ AuthTelemetry .modifyConnection(
185+ action = " Delete cache file" ,
186+ source = " invalidateAccessToken" ,
187+ result = Result .Failed ,
188+ reason = " Failed to invalidate Access Token" ,
189+ reasonDesc = e.message ? : e::class .java.name
190+ )
191+ throw e
192+ }
147193 }
148194
149195 private fun clientRegistrationCache (ssoRegion : String ): Path = cacheDir.resolve(" aws-toolkit-jetbrains-client-id-$ssoRegion .json" )
@@ -170,15 +216,36 @@ class DiskCache(
170216 return cacheDir.resolve(fileName)
171217 }
172218
173- private fun loadClientRegistration (inputStream : InputStream ) =
174- tryOrNull {
219+ private fun loadClientRegistration (inputStream : InputStream ): ClientRegistration ? {
220+ var stage = LoadCredentialStage .VALIDATE_CREDENTIALS
221+ try {
175222 val clientRegistration = objectMapper.readValue<ClientRegistration >(inputStream)
223+ stage = LoadCredentialStage .CHECK_EXPIRATION
176224 if (clientRegistration.expiresAt.isNotExpired()) {
177- clientRegistration
225+ return clientRegistration
178226 } else {
179- null
227+ LOG .warn(" Client Registration is expired" )
228+ AuthTelemetry .modifyConnection(
229+ action = " Validate Credentials" ,
230+ source = " loadClientRegistration" ,
231+ result = Result .Failed ,
232+ reason = " Failed to load Client Registration" ,
233+ reasonDesc = " Load Step:$stage failed: Client Registration is expired"
234+ )
235+ return null
180236 }
237+ } catch (e: Exception ) {
238+ LOG .warn(" Client Registration could not be read" )
239+ AuthTelemetry .modifyConnection(
240+ action = " Validate Credentials" ,
241+ source = " loadClientRegistration" ,
242+ result = Result .Failed ,
243+ reason = " Failed to load Client Registration" ,
244+ reasonDesc = " Load Step:$stage failed: File could not be read"
245+ )
246+ return null
181247 }
248+ }
182249
183250 private fun loadAccessToken (inputStream : InputStream ) = tryOrNull {
184251 val accessToken = objectMapper.readValue<AccessToken >(inputStream)
@@ -202,11 +269,22 @@ class DiskCache(
202269
203270 private fun writeKey (path : Path , consumer : (OutputStream ) -> Unit ) {
204271 LOG .debug { " writing to $path " }
205- path.tryDirOp(LOG ) { createParentDirectories() }
272+ try {
273+ path.tryDirOp(LOG ) { createParentDirectories() }
206274
207- path.tryFileOp(LOG ) {
208- touch(restrictToOwner = true )
209- outputStream().use(consumer)
275+ path.tryFileOp(LOG ) {
276+ touch(restrictToOwner = true )
277+ outputStream().use(consumer)
278+ }
279+ } catch (e: Exception ) {
280+ AuthTelemetry .modifyConnection(
281+ action = " Write file" ,
282+ source = " writeKey" ,
283+ result = Result .Failed ,
284+ reason = " Failed to write to cache" ,
285+ reasonDesc = e.message ? : e::class .java.name
286+ )
287+ throw e
210288 }
211289 }
212290
@@ -230,6 +308,12 @@ class DiskCache(
230308 }
231309 }
232310
311+ private enum class LoadCredentialStage {
312+ ACCESS_FILE ,
313+ VALIDATE_CREDENTIALS ,
314+ CHECK_EXPIRATION ,
315+ }
316+
233317 companion object {
234318 val EXPIRATION_THRESHOLD = Duration .ofMinutes(15 )
235319 private val LOG = getLogger<DiskCache >()
0 commit comments