Skip to content

Commit

Permalink
Merge branch 'canary' into add/error-if-fetch-do-not-return-response
Browse files Browse the repository at this point in the history
  • Loading branch information
mabels committed Oct 11, 2022
2 parents 2309168 + 9e1d04d commit 63aac1b
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 3 deletions.
10 changes: 8 additions & 2 deletions packages/next/build/webpack/loaders/next-image-loader.js
Expand Up @@ -17,16 +17,22 @@ function nextImageLoader(content) {
opts
)
const outputPath = assetPrefix + '/_next' + interpolatedName

let extension = loaderUtils.interpolateName(this, '[ext]', opts)
if (extension === 'jpg') {
extension = 'jpeg'
}

const imageSizeSpan = imageLoaderSpan.traceChild('image-size-calculation')
const imageSize = await imageSizeSpan.traceAsyncFn(() =>
getImageSize(content, extension)
getImageSize(content, extension).catch((err) => err)
)

if (imageSize instanceof Error) {
const err = imageSize
err.name = 'InvalidImageFormatError'
throw err
}

let blurDataURL
let blurWidth
let blurHeight
Expand Down
Expand Up @@ -118,3 +118,35 @@ export async function getNotFoundError(
return input
}
}

export async function getImageError(
compilation: any,
input: any,
err: Error
): Promise<SimpleWebpackError | false> {
if (err.name !== 'InvalidImageFormatError') {
return false
}

const moduleTrace = getModuleTrace(input, compilation)
const { origin, module } = moduleTrace[0] || {}
if (!origin || !module) {
return false
}
const page = origin.rawRequest.replace(/^private-next-pages/, './pages')
const importedFile = module.rawRequest
const source = origin.originalSource().buffer().toString('utf8') as string
let lineNumber = -1
source.split('\n').some((line) => {
lineNumber++
return line.includes(importedFile)
})
return new SimpleWebpackError(
`${chalk.cyan(page)}:${chalk.yellow(lineNumber.toString())}`,
chalk.red
.bold('Error')
.concat(
`: Image import "${importedFile}" is not a valid image file. The image may be corrupted or an unsupported format.`
)
)
}
Expand Up @@ -5,7 +5,7 @@ import type { webpack } from 'next/dist/compiled/webpack/webpack'
import { getBabelError } from './parseBabel'
import { getCssError } from './parseCss'
import { getScssError } from './parseScss'
import { getNotFoundError } from './parseNotFoundError'
import { getNotFoundError, getImageError } from './parseNotFoundError'
import { SimpleWebpackError } from './simpleWebpackError'
import isError from '../../../../lib/is-error'
import { getRscError } from './parseRSC'
Expand Down Expand Up @@ -71,6 +71,11 @@ export async function getModuleBuildError(
return notFoundError
}

const imageError = await getImageError(compilation, input, err)
if (imageError !== false) {
return imageError
}

const babel = getBabelError(sourceFilename, err)
if (babel !== false) {
return babel
Expand Down
14 changes: 14 additions & 0 deletions test/integration/image-future/invalid-image-import/pages/index.js
@@ -0,0 +1,14 @@
import React from 'react'
import Image from 'next/future/image'
import test from '../public/invalid.svg'

const Page = () => {
return (
<div>
<h1>Try to import and invalid image file</h1>
<Image id="invalid-img" src={test} width={400} height={400} />
</div>
)
}

export default Page
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -0,0 +1,70 @@
/* eslint-env jest */

import { join } from 'path'
import {
findPort,
getRedboxHeader,
getRedboxSource,
hasRedbox,
killApp,
launchApp,
nextBuild,
} from 'next-test-utils'
import webdriver from 'next-webdriver'

const appDir = join(__dirname, '../')
let appPort: number
let app
let stderr = ''
const msg =
'Error: Image import "../public/invalid.svg" is not a valid image file. The image may be corrupted or an unsupported format.'

function runTests({ isDev }) {
it('should show error', async () => {
if (isDev) {
const browser = await webdriver(appPort, '/')
expect(await hasRedbox(browser)).toBe(true)
expect(await getRedboxHeader(browser)).toBe('Failed to compile')
expect(await getRedboxSource(browser)).toBe(`./pages/index.js:3\n${msg}`)
expect(stderr).toContain(msg)
} else {
expect(stderr).toContain(msg)
}
})
}

describe('Missing Import Image Tests', () => {
describe('dev mode', () => {
beforeAll(async () => {
stderr = ''
appPort = await findPort()
app = await launchApp(appDir, appPort, {
onStderr(msg) {
stderr += msg || ''
},
})
})
afterAll(async () => {
if (app) {
await killApp(app)
}
})

runTests({ isDev: true })
})

describe('server mode', () => {
beforeAll(async () => {
stderr = ''
const result = await nextBuild(appDir, [], { stderr: true })
stderr = result.stderr
})
afterAll(async () => {
if (app) {
await killApp(app)
}
})

runTests({ isDev: false })
})
})

0 comments on commit 63aac1b

Please sign in to comment.