File tree Expand file tree Collapse file tree
components/ErrorBoundaries Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -6,13 +6,13 @@ import React from 'react';
66import AppErrorDialog from '../AppErrorDialog' ;
77import * as Sentry from '@sentry/browser' ;
88
9- interface AppErrorBoundaryProps {
9+ type AppErrorBoundaryProps = {
1010 children ?: React . ReactNode ;
11- }
11+ } ;
1212
13- interface AppErrorBoundaryState {
13+ type AppErrorBoundaryState = {
1414 error : Error | undefined ;
15- }
15+ } ;
1616
1717class AppErrorBoundary extends React . Component <
1818 AppErrorBoundaryProps ,
@@ -22,7 +22,7 @@ class AppErrorBoundary extends React.Component<
2222 error : undefined | Error ;
2323 } ;
2424
25- constructor ( props : { } ) {
25+ constructor ( props : AppErrorBoundaryProps ) {
2626 super ( props ) ;
2727 this . state = { error : undefined } ;
2828 }
@@ -38,7 +38,7 @@ class AppErrorBoundary extends React.Component<
3838
3939 render ( ) {
4040 const { error } = this . state ;
41- return error ? < AppErrorDialog /> : ( this . props as any ) . children ;
41+ return error ? < AppErrorDialog /> : this . props . children ;
4242 }
4343}
4444
Original file line number Diff line number Diff line change @@ -5,3 +5,8 @@ app-general-err-message = Something went wrong. Please try again later.
55
66# Specific handling for issues when bad or missing query parameters are detected
77app-query-parameter-err-heading = Bad Request: Invalid Query Parameters
8+
9+ # Specific handler for issues where something went side with the session. Maybe it did't have proper permissions,
10+ # or maybe the session token is stale and the user needs to sign back in again.
11+ app-invalid-session-err-heading = Invalid Session
12+ app-invalid-session-err-message = Please sign out and sign in again.
Original file line number Diff line number Diff line change @@ -31,4 +31,12 @@ storiesOf('Components/AppErrorDialog', module)
3131 >
3232 < AppErrorDialog errorType = "query-parameter-violation" />
3333 </ AppLocalizationProvider >
34+ ) )
35+ . add ( 'invalid session' , ( ) => (
36+ < AppLocalizationProvider
37+ baseDir = "./locales"
38+ userLocales = { navigator . languages }
39+ >
40+ < AppErrorDialog errorType = "invalid-session" />
41+ </ AppLocalizationProvider >
3442 ) ) ;
Original file line number Diff line number Diff line change @@ -14,4 +14,15 @@ describe('AppErrorDialog', () => {
1414
1515 expect ( queryByTestId ( 'error-loading-app' ) ) . toBeInTheDocument ( ) ;
1616 } ) ;
17+
18+ it ( 'can trigger another signin attempt in invalid-session case' , async ( ) => {
19+ const { queryByText } = renderWithLocalizationProvider (
20+ < AppErrorDialog errorType = "invalid-session" />
21+ ) ;
22+
23+ expect ( queryByText ( 'Invalid Session' ) ) . toBeInTheDocument ( ) ;
24+ expect (
25+ queryByText ( 'Please sign out and sign in again.' )
26+ ) . toBeInTheDocument ( ) ;
27+ } ) ;
1728} ) ;
Original file line number Diff line number Diff line change 55import React from 'react' ;
66import { Localized } from '@fluent/react' ;
77
8- export type ErrorType = 'general' | 'query-parameter-violation' ;
8+ export type ErrorType =
9+ | 'general'
10+ | 'query-parameter-violation'
11+ | 'invalid-session' ;
912
1013const AppErrorDialog = ( { errorType } : { errorType ?: ErrorType } ) => {
1114 if ( errorType == null ) {
@@ -43,6 +46,24 @@ const AppErrorDialog = ({ errorType }: { errorType?: ErrorType }) => {
4346 </ p >
4447 </ Localized >
4548 ) }
49+
50+ { errorType === 'invalid-session' && (
51+ < >
52+ < Localized id = "app-invalid-session-err-heading" >
53+ < h2
54+ className = "text-grey-900 font-header text-lg font-bold mb-3"
55+ data-testid = "error-invalid-session"
56+ >
57+ Invalid Session
58+ </ h2 >
59+ </ Localized >
60+ < Localized id = "app-invalid-session-err-message" >
61+ < p className = "text-grey-400" >
62+ Please sign out and sign in again.
63+ </ p >
64+ </ Localized >
65+ </ >
66+ ) }
4667 </ div >
4768 </ div >
4869 ) ;
Original file line number Diff line number Diff line change 44
55import React from 'react' ;
66import { AppError } from '.' ;
7- import {
8-
9- UrlQueryData ,
10- } from '../../lib/model-data' ;
7+ import { UrlQueryData } from '../../lib/model-data' ;
118import { withLocalization } from 'fxa-react/lib/storybooks' ;
129
1310import { Meta } from '@storybook/react' ;
@@ -43,3 +40,12 @@ export const QueryParamValidationError = () => {
4340 // AppError should display a list of the validation errors
4441 return < AppError error = { validationError } /> ;
4542} ;
43+
44+ export const InvalidSessionError = ( ) => {
45+ const error = {
46+ name : '' ,
47+ message : 'Unconfirmed Session' ,
48+ errno : 138 ,
49+ } ;
50+ return < AppError error = { error } /> ;
51+ } ;
Original file line number Diff line number Diff line change @@ -6,6 +6,7 @@ import React, { ReactNode } from 'react';
66import { ModelValidationErrors } from '../../lib/model-data' ;
77import * as Sentry from '@sentry/browser' ;
88import AppErrorDialog from 'fxa-react/components/AppErrorDialog' ;
9+ import { AuthUiErrors , isAuthUiError } from '../../lib/auth-errors/auth-errors' ;
910
1011/**
1112 * Handles errors that might occur in fxa-settings
@@ -47,6 +48,16 @@ export class AppErrorBoundary extends React.Component<{ children: ReactNode }> {
4748}
4849
4950export const AppError = ( { error } : { error ?: Error } ) => {
51+ // Special handling for invalid session states
52+ if (
53+ isAuthUiError ( error ) &&
54+ ( error . errno === AuthUiErrors . INVALID_TOKEN . errno ||
55+ error . errno === AuthUiErrors . UNVERIFIED_SESSION . errno )
56+ ) {
57+ // TODO: Add functionality so that is easy for a user to sign back in.
58+ return < AppErrorDialog errorType = "invalid-session" /> ;
59+ }
60+
5061 // Special handling for validation errors
5162 if ( error instanceof ModelValidationErrors ) {
5263 return < AppErrorDialog errorType = "query-parameter-violation" /> ;
Original file line number Diff line number Diff line change @@ -56,7 +56,8 @@ const ERRORS = {
5656 } ,
5757 INVALID_TOKEN : {
5858 errno : 110 ,
59- message : 'Invalid token' ,
59+ message : 'Invalid session. Please sign out and sign in again.' ,
60+ version : 2 ,
6061 } ,
6162 INVALID_TIMESTAMP : {
6263 errno : 111 ,
@@ -139,8 +140,8 @@ const ERRORS = {
139140 } ,
140141 UNVERIFIED_SESSION : {
141142 errno : 138 ,
142- message : 'Unconfirmed session' ,
143- version : 2 ,
143+ message : 'Unconfirmed session. Please sign out and sign in again. ' ,
144+ version : 3 ,
144145 } ,
145146 EMAIL_PRIMARY_EXISTS : {
146147 errno : 139 ,
@@ -690,3 +691,14 @@ export const AuthUiErrorNos: {
690691 errnos . push ( x . errno ) ;
691692 }
692693} ) ( ) ;
694+
695+ /**
696+ * TypeGuard for AuthUiErrors
697+ */
698+ export function isAuthUiError ( error : any ) : error is AuthUiError {
699+ return (
700+ typeof error === 'object' &&
701+ typeof error ?. errno === 'number' &&
702+ typeof error ?. message === 'string'
703+ ) ;
704+ }
Original file line number Diff line number Diff line change @@ -4,6 +4,7 @@ auth-error-102 = Unknown account
44auth-error-103 = Incorrect password
55auth-error-105-2 = Invalid confirmation code
66auth-error-110 = Invalid token
7+ auth-error-110-2 = Invalid session. Please sign out and sign in again.
78# Error shown to users when they have attempted a request (e.g., requesting a password reset) too many times
89# and their requests have been throttled, but the specific amount of time before they can retry is unknown.
910auth-error-114-generic = You’ve tried too many times. Please try again later.
@@ -16,6 +17,7 @@ auth-error-114 = You’ve tried too many times. Please try again { $retryAfter }
1617auth-error-125 = The request was blocked for security reasons
1718auth-error-129-2 = You entered an invalid phone number. Please check it and try again.
1819auth-error-138-2 = Unconfirmed session
20+ auth-error-138-3 = Unconfirmed Session. Please sign out and sign in again.
1921auth-error-139 = Secondary email must be different than your account email
2022auth-error-155 = TOTP token not found
2123# Error shown when the user submits an invalid backup authentication code
You can’t perform that action at this time.
0 commit comments