Skip to content

Commit 3ed4d6a

Browse files
Fix remaining canvas context null checks and silent crop failures
- Add proper null checks for canvas.getContext('2d') on lines 189 and 283 - Add user-facing error notification for crop submission failures - Display error message using Helper component when crop operation fails - Remove non-null assertion operators for type safety 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent f586e8a commit 3ed4d6a

File tree

1 file changed

+30
-7
lines changed

1 file changed

+30
-7
lines changed

src/components/@molecules/ProfileEditor/Header/HeaderCrop.tsx

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { useCallback, useEffect, useRef, useState } from 'react'
44
import { useTranslation } from 'react-i18next'
55
import styled, { css } from 'styled-components'
66

7-
import { Button, Dialog, Slider } from '@ensdomains/thorin'
7+
import { Button, Dialog, Helper, Slider } from '@ensdomains/thorin'
88

99
import CropBorderSVG from '@app/assets/HeaderCropBorder.svg'
1010
import CropFrameSVG from '@app/assets/HeaderCropFrame.svg'
@@ -186,7 +186,14 @@ const useCanvasDrawing = (
186186
const { maxX, maxY, cropWidth, cropHeight } = getHeaderVars(canvas)
187187
// eslint-disable-next-line prefer-const
188188
let { x, y, w, h, mx, my, moving } = coordinatesRef.current
189-
const ctx = canvas.getContext('2d')!
189+
const ctx = canvas.getContext('2d')
190+
191+
if (!ctx) {
192+
if (process.env.NODE_ENV === 'development') {
193+
console.error('Failed to get canvas context')
194+
}
195+
return
196+
}
190197

191198
ctx.clearRect(0, 0, canvas.width, canvas.height)
192199
x += mx
@@ -273,7 +280,14 @@ const useImageLoader = (
273280
y = maxY
274281
}
275282

276-
const ctx = canvasRef.current.getContext('2d')!
283+
const ctx = canvasRef.current.getContext('2d')
284+
if (!ctx) {
285+
if (process.env.NODE_ENV === 'development') {
286+
console.error('Failed to get canvas context')
287+
}
288+
return
289+
}
290+
277291
ctx.drawImage(image, x, y, w, h)
278292
coordinatesRef.current = {
279293
x,
@@ -588,9 +602,13 @@ const useCropSubmission = (
588602
coordinatesRef: React.MutableRefObject<Coordinates>,
589603
setDataURL: (dataURL: string) => void,
590604
) => {
605+
const [cropError, setCropError] = useState<string | null>(null)
606+
591607
const handleSubmit = useCallback(() => {
592608
if (!canvasRef.current) return
593609

610+
setCropError(null) // Clear any previous errors
611+
594612
try {
595613
const { cropWidth, cropHeight, maxX, maxY } = getHeaderVars(canvasRef.current)
596614
const cropCanvas = document.createElement('canvas')
@@ -650,12 +668,12 @@ const useCropSubmission = (
650668
if (process.env.NODE_ENV === 'development') {
651669
console.error('Failed to crop image:', error)
652670
}
653-
// In production, we could show a user-friendly error message
654-
// For now, fail silently to maintain existing behavior
671+
// Set user-facing error message
672+
setCropError('Failed to crop image. Please try again.')
655673
}
656674
}, [canvasRef, coordinatesRef, setDataURL])
657675

658-
return { handleSubmit }
676+
return { handleSubmit, cropError }
659677
}
660678

661679
export const CropComponent = ({
@@ -715,7 +733,7 @@ export const CropComponent = ({
715733
)
716734

717735
// Initialize crop submission
718-
const { handleSubmit } = useCropSubmission(canvasRef, coordinatesRef, setDataURL)
736+
const { handleSubmit, cropError } = useCropSubmission(canvasRef, coordinatesRef, setDataURL)
719737

720738
return (
721739
<>
@@ -743,6 +761,11 @@ export const CropComponent = ({
743761
</SliderContainer>
744762
</EditImageContainer>
745763
</Dialog.Content>
764+
{cropError && (
765+
<Helper data-testid="crop-error" alert="error">
766+
{cropError}
767+
</Helper>
768+
)}
746769
<Dialog.Footer
747770
leading={<AvCancelButton handleCancel={handleCancel} />}
748771
trailing={

0 commit comments

Comments
 (0)