Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(native-app): add barcode session error #17623

Merged
merged 7 commits into from
Jan 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions apps/native/app/src/messages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,8 @@ export const en: TranslatedMessages = {
'walletPass.barcodeErrorNotConnected':
'Not possible to scan barcode if the device is not connected to the internet.',
'walletPass.barcodeErrorFailedToFetch': 'Could not fetch barcode',
'walletPass.barcodeErrorBadSession':
'Too little time since license was accessed on another device',
'walletPass.validLicense': 'Valid',
'walletPass.expiredLicense': 'Expired',
'walletPass.passportNumber': 'Passport number: {licenseNumber}',
Expand Down
2 changes: 2 additions & 0 deletions apps/native/app/src/messages/is.ts
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,8 @@ export const is = {
'walletPass.barcodeErrorNotConnected':
'Ekki er hægt að skanna skírteini nema að tækið sé nettengt.',
'walletPass.barcodeErrorFailedToFetch': 'Ekki tókst að sækja barkóða',
'walletPass.barcodeErrorBadSession':
'Of stutt síðan skírteini var sótt á öðru tæki',
'walletPass.validLicense': 'Í gildi',
'walletPass.expiredLicense': 'Útrunnið',
'walletPass.passportNumber': 'Númer vegabréfs: {licenseNumber}',
Expand Down
2 changes: 1 addition & 1 deletion apps/native/app/src/screens/wallet-pass/wallet-pass.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ export const WalletPassScreen: NavigationFunctionComponent<{
type={licenseType}
title={data?.payload?.metadata?.name ?? undefined}
loading={res.loading}
error={!!res.error}
error={res.error}
logo={
isBarcodeEnabled &&
data?.license?.type === GenericLicenseType.DriversLicense
Expand Down
15 changes: 13 additions & 2 deletions apps/native/app/src/ui/lib/card/license-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
ViewStyle,
} from 'react-native'
import styled, { useTheme } from 'styled-components/native'
import { ApolloError } from '@apollo/client'

import { Barcode } from '../barcode/barcode'
import { Skeleton } from '../skeleton/skeleton'
Expand All @@ -22,6 +23,10 @@ import { dynamicColor } from '../../utils/dynamic-color'
import { Typography } from '../typography/typography'
import { screenWidth } from '../../../utils/dimensions'
import { BARCODE_MAX_WIDTH } from '../../../screens/wallet-pass/wallet-pass.constants'
import {
findProblemInApolloError,
ProblemType,
} from '@island.is/shared/problem'

const Host = styled(Animated.View)`
position: relative;
Expand Down Expand Up @@ -123,7 +128,7 @@ interface LicenseCardProps {
backgroundColor?: string
showBarcodeOfflineMessage?: boolean
loading?: boolean
error?: boolean
error?: ApolloError
barcode?: {
value?: string | null
loading?: boolean
Expand Down Expand Up @@ -166,6 +171,10 @@ export function LicenseCard({
: screenWidth - theme.spacing[4] * 2 - theme.spacing.smallGutter * 2
const barcodeHeight = barcodeWidth / 3

const badSessionError = error
? findProblemInApolloError(error as any, [ProblemType.BAD_SESSION])
: undefined
thoreyjona marked this conversation as resolved.
Show resolved Hide resolved

return (
<Host>
<BackgroundImage
Expand Down Expand Up @@ -297,7 +306,9 @@ export function LicenseCard({
<OfflineMessage variant="body3" style={{ opacity: 1 }}>
{intl.formatMessage({
id: error
? 'walletPass.barcodeErrorFailedToFetch'
? badSessionError
? 'walletPass.barcodeErrorBadSession'
: 'walletPass.barcodeErrorFailedToFetch'
: 'walletPass.barcodeErrorNotConnected',
})}
</OfflineMessage>
Expand Down
31 changes: 31 additions & 0 deletions libs/shared/problem/src/utils/findProblemInApolloError.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,44 @@ describe('findProblemInApolloError', () => {
expect(problem).toMatchObject({ type: ProblemType.HTTP_NOT_FOUND })
})

it('return first problem matching types when problem is nested in exception object', () => {
// Arrange
const error = new ApolloError({
graphQLErrors: [
new GraphQLError('Error', null, null, null, null, null, {
exception: {
problem: { type: ProblemType.HTTP_BAD_REQUEST },
},
}),
new GraphQLError('Error', null, null, null, null, null, {
exception: {
problem: { type: ProblemType.HTTP_NOT_FOUND },
},
}),
],
})

// Act
const problem = findProblemInApolloError(error, [
ProblemType.HTTP_NOT_FOUND,
])

// Assert
expect(problem).toMatchObject({ type: ProblemType.HTTP_NOT_FOUND })
})

it('return undefined if no problem matches types', () => {
// Arrange
const error = new ApolloError({
graphQLErrors: [
new GraphQLError('Error', null, null, null, null, null, {
problem: { type: ProblemType.HTTP_BAD_REQUEST },
}),
new GraphQLError('Error', null, null, null, null, null, {
exception: {
problem: { type: ProblemType.HTTP_BAD_REQUEST },
},
}),
],
})

Expand Down
26 changes: 19 additions & 7 deletions libs/shared/problem/src/utils/findProblemInApolloError.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,34 @@
import type { ApolloError } from '@apollo/client'
import { Problem } from '../Problem'

interface ProblemExtensions {
problem?: Problem
exception?: {
problem?: Problem
}
}

export const findProblemInApolloError = (
error: ApolloError | undefined,
types?: string[],
): Problem | undefined => {
if (!error) {
return undefined
}
const graphQLError = error.graphQLErrors.find((value) => {
const problem = value.extensions?.problem as Problem | undefined
return problem && (!types || types.includes(problem.type))
})

if (!graphQLError) {
const problems = error.graphQLErrors
.map((value) => {
const extensions = value.extensions as ProblemExtensions | undefined
const problem = extensions?.problem || extensions?.exception?.problem
if (problem && (!types || types.includes(problem.type))) {
return problem
}
})
.filter((problem) => problem) as Problem[]

if (problems.length === 0) {
return undefined
}

// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
return graphQLError.extensions!.problem as Problem
return problems[0]
}
Loading