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

Add error when href interpolation fails #16946

Merged
merged 8 commits into from
Sep 10, 2020

Conversation

ijjk
Copy link
Member

@ijjk ijjk commented Sep 8, 2020

This adds an error when interpolation fails to make sure invalid hrefs aren't accidentally used and an invalid URL is built.

Closes: #16944

@ijjk
Copy link
Member Author

ijjk commented Sep 8, 2020

Stats from current PR

Default Server Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
buildDuration 12.7s 12.8s ⚠️ +78ms
nodeModulesSize 56.7 MB 56.7 MB ⚠️ +863 B
Page Load Tests Overall increase ✓
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
/ failed reqs 0 0
/ total time (seconds) 2.289 2.239 -0.05
/ avg req/sec 1091.97 1116.42 +24.45
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.218 1.214 0
/error-in-render avg req/sec 2052.61 2058.83 +6.22
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
677f882d2ed8..a2cc.js gzip 10.8 kB 10.9 kB ⚠️ +109 B
framework.HASH.js gzip 39 kB 39 kB
main-4d826ad..023b.js gzip 7.08 kB 7.08 kB
webpack-e067..f178.js gzip 751 B 751 B
Overall change 57.6 kB 57.7 kB ⚠️ +109 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
677f882d2ed8..dule.js gzip 6.62 kB 6.7 kB ⚠️ +85 B
framework.HA..dule.js gzip 39 kB 39 kB
main-4dbc74f..dule.js gzip 6.14 kB 6.14 kB
webpack-07c5..dule.js gzip 751 B 751 B
Overall change 52.5 kB 52.6 kB ⚠️ +85 B
Legacy Client Bundles (polyfills)
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
polyfills-4b..e242.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
_app-9a0b9e1..b37e.js gzip 1.28 kB 1.28 kB
_error-ed1b0..8fbd.js gzip 3.44 kB 3.44 kB
hooks-89731c..c609.js gzip 887 B 887 B
index-17468f..5d83.js gzip 227 B 227 B
link-d2344ce..8b36.js gzip 1.3 kB 1.3 kB
routerDirect..924c.js gzip 284 B 284 B
withRouter-7..c13d.js gzip 284 B 284 B
Overall change 7.71 kB 7.71 kB
Client Pages Modern
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
_app-75d3a82..dule.js gzip 625 B 625 B
_error-4469a..dule.js gzip 2.29 kB 2.29 kB
hooks-cbf13f..dule.js gzip 387 B 387 B
index-b9a643..dule.js gzip 226 B 226 B
link-f8c0daf..dule.js gzip 1.26 kB 1.26 kB
routerDirect..dule.js gzip 284 B 284 B
withRouter-f..dule.js gzip 282 B 282 B
Overall change 5.36 kB 5.36 kB
Client Build Manifests
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
_buildManifest.js gzip 322 B 322 B
_buildManife..dule.js gzip 329 B 329 B
Overall change 651 B 651 B
Rendered Page Sizes Overall decrease ✓
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
index.html gzip 970 B 968 B -2 B
link.html gzip 977 B 974 B -3 B
withRouter.html gzip 963 B 962 B -1 B
Overall change 2.91 kB 2.9 kB -6 B

Diffs

Diff for 677f882d2ed8..c3c4f674d.js
@@ -867,18 +867,22 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               result = _interpolateAs.result,
               params = _interpolateAs.params;
 
-            interpolatedAs = (0, _utils.formatWithValidation)({
-              pathname: result,
-              hash: finalUrl.hash,
-              query: omitParmsFromQuery(query, params)
-            });
+            if (result) {
+              interpolatedAs = (0, _utils.formatWithValidation)({
+                pathname: result,
+                hash: finalUrl.hash,
+                query: omitParmsFromQuery(query, params)
+              });
+            }
           } // if the origin didn't change, it means we received a relative href
 
           var resolvedHref =
             finalUrl.origin === base.origin
               ? finalUrl.href.slice(finalUrl.origin.length)
               : finalUrl.href;
-          return resolveAs ? [resolvedHref, interpolatedAs] : resolvedHref;
+          return resolveAs
+            ? [resolvedHref, interpolatedAs || resolvedHref]
+            : resolvedHref;
         } catch (_) {
           return resolveAs ? [urlAsString] : urlAsString;
         }
@@ -1331,7 +1335,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             resolvedAs = delBasePath(resolvedAs);
 
                             if (!(0, _isDynamic.isDynamicRoute)(route)) {
-                              _context.next = 47;
+                              _context.next = 54;
                               break;
                             }
 
@@ -1374,33 +1378,56 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             );
 
                           case 44:
-                            _context.next = 47;
+                            _context.next = 54;
                             break;
 
                           case 46:
-                            if (route === asPathname) {
-                              (_interpolateAs2 = interpolateAs(
-                                route,
-                                asPathname,
-                                query
-                              )),
-                                (result = _interpolateAs2.result),
-                                (params = _interpolateAs2.params);
-                              as = (0, _utils.formatWithValidation)(
-                                Object.assign({}, parsedAs, {
-                                  pathname: result,
-                                  query: omitParmsFromQuery(query, params)
-                                })
-                              );
-                            } else {
-                              // Merge params into `query`, overwriting any specified in search
-                              Object.assign(query, routeMatch);
+                            if (!(route === asPathname)) {
+                              _context.next = 53;
+                              break;
+                            }
+
+                            (_interpolateAs2 = interpolateAs(
+                              route,
+                              asPathname,
+                              query
+                            )),
+                              (result = _interpolateAs2.result),
+                              (params = _interpolateAs2.params);
+
+                            if (result) {
+                              _context.next = 50;
+                              break;
                             }
 
-                          case 47:
+                            throw new Error(
+                              "Interpolation failed for href ("
+                                .concat(
+                                  route,
+                                  ") due to not all param values being provided in the query, needed param values ("
+                                )
+                                .concat(params.join(", "), ")\n") +
+                                "Read more: https://err.sh/next.js/href-interpolation-failed"
+                            );
+
+                          case 50:
+                            as = (0, _utils.formatWithValidation)(
+                              Object.assign({}, parsedAs, {
+                                pathname: result,
+                                query: omitParmsFromQuery(query, params)
+                              })
+                            );
+                            _context.next = 54;
+                            break;
+
+                          case 53:
+                            // Merge params into `query`, overwriting any specified in search
+                            Object.assign(query, routeMatch);
+
+                          case 54:
                             Router.events.emit("routeChangeStart", as);
-                            _context.prev = 48;
-                            _context.next = 51;
+                            _context.prev = 55;
+                            _context.next = 58;
                             return this.getRouteInfo(
                               route,
                               pathname,
@@ -1409,7 +1436,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               shallow
                             );
 
-                          case 51:
+                          case 58:
                             routeInfo = _context.sent;
                             (error = routeInfo.error),
                               (props = routeInfo.props),
@@ -1424,7 +1451,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                 props.pageProps.__N_REDIRECT
                               )
                             ) {
-                              _context.next = 62;
+                              _context.next = 69;
                               break;
                             }
 
@@ -1433,7 +1460,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             // it's not
 
                             if (!destination.startsWith("/")) {
-                              _context.next = 60;
+                              _context.next = 67;
                               break;
                             }
 
@@ -1443,7 +1470,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             this._resolveHref(parsedHref, pages);
 
                             if (!pages.includes(parsedHref.pathname)) {
-                              _context.next = 60;
+                              _context.next = 67;
                               break;
                             }
 
@@ -1457,21 +1484,21 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               )
                             );
 
-                          case 60:
+                          case 67:
                             window.location.href = destination;
                             return _context.abrupt(
                               "return",
                               new Promise(function() {})
                             );
 
-                          case 62:
+                          case 69:
                             Router.events.emit("beforeHistoryChange", as);
                             this.changeState(method, url, as, options);
 
                             if (false) {
                             }
 
-                            _context.next = 67;
+                            _context.next = 74;
                             return this.set(
                               route,
                               pathname,
@@ -1483,9 +1510,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               else throw e;
                             });
 
-                          case 67:
+                          case 74:
                             if (!error) {
-                              _context.next = 70;
+                              _context.next = 77;
                               break;
                             }
 
@@ -1496,28 +1523,28 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             );
                             throw error;
 
-                          case 70:
+                          case 77:
                             if (false) {
                             }
 
                             Router.events.emit("routeChangeComplete", as);
                             return _context.abrupt("return", true);
 
-                          case 75:
-                            _context.prev = 75;
-                            _context.t0 = _context["catch"](48);
+                          case 82:
+                            _context.prev = 82;
+                            _context.t0 = _context["catch"](55);
 
                             if (!_context.t0.cancelled) {
-                              _context.next = 79;
+                              _context.next = 86;
                               break;
                             }
 
                             return _context.abrupt("return", false);
 
-                          case 79:
+                          case 86:
                             throw _context.t0;
 
-                          case 80:
+                          case 87:
                           case "end":
                             return _context.stop();
                         }
@@ -1525,7 +1552,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     },
                     _callee,
                     this,
-                    [[48, 75]]
+                    [[55, 82]]
                   );
                 })
               );
Diff for 677f882d2ed8..45.module.js
@@ -720,18 +720,23 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               finalUrl.pathname,
               query
             );
-            interpolatedAs = (0, _utils.formatWithValidation)({
-              pathname: result,
-              hash: finalUrl.hash,
-              query: omitParmsFromQuery(query, params)
-            });
+
+            if (result) {
+              interpolatedAs = (0, _utils.formatWithValidation)({
+                pathname: result,
+                hash: finalUrl.hash,
+                query: omitParmsFromQuery(query, params)
+              });
+            }
           } // if the origin didn't change, it means we received a relative href
 
           var resolvedHref =
             finalUrl.origin === base.origin
               ? finalUrl.href.slice(finalUrl.origin.length)
               : finalUrl.href;
-          return resolveAs ? [resolvedHref, interpolatedAs] : resolvedHref;
+          return resolveAs
+            ? [resolvedHref, interpolatedAs || resolvedHref]
+            : resolvedHref;
         } catch (_) {
           return resolveAs ? [urlAsString] : urlAsString;
         }
@@ -1114,6 +1119,19 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               }
             } else if (route === asPathname) {
               var { result, params } = interpolateAs(route, asPathname, query);
+
+              if (!result) {
+                throw new Error(
+                  "Interpolation failed for href ("
+                    .concat(
+                      route,
+                      ") due to not all param values being provided in the query, needed param values ("
+                    )
+                    .concat(params.join(", "), ")\n") +
+                    "Read more: https://err.sh/next.js/href-interpolation-failed"
+                );
+              }
+
               as = (0, _utils.formatWithValidation)(
                 Object.assign({}, parsedAs, {
                   pathname: result,
Diff for index.html
@@ -25,7 +25,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.7d132ab979d135defe45.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.184bcde6de1f866fd9c5.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -118,13 +118,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.3708ec5b82fc3c4f674d.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.474d66d4231ddfc7d752.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.7d132ab979d135defe45.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.184bcde6de1f866fd9c5.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for link.html
@@ -25,7 +25,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.7d132ab979d135defe45.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.184bcde6de1f866fd9c5.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -123,13 +123,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.3708ec5b82fc3c4f674d.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.474d66d4231ddfc7d752.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.7d132ab979d135defe45.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.184bcde6de1f866fd9c5.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for withRouter.html
@@ -25,7 +25,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.7d132ab979d135defe45.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.184bcde6de1f866fd9c5.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -118,13 +118,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.3708ec5b82fc3c4f674d.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.474d66d4231ddfc7d752.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.7d132ab979d135defe45.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.184bcde6de1f866fd9c5.module.js"
       async=""
       crossorigin="anonymous"
       type="module"

Serverless Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
buildDuration 13.8s 14s ⚠️ +191ms
nodeModulesSize 56.7 MB 56.7 MB ⚠️ +863 B
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
677f882d2ed8..a2cc.js gzip 10.8 kB N/A N/A
framework.HASH.js gzip 39 kB 39 kB
main-4d826ad..023b.js gzip 7.08 kB 7.08 kB
webpack-e067..f178.js gzip 751 B 751 B
677f882d2ed8..364e.js gzip N/A 10.9 kB N/A
Overall change 57.6 kB 57.7 kB ⚠️ +109 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
677f882d2ed8..dule.js gzip 6.62 kB N/A N/A
framework.HA..dule.js gzip 39 kB 39 kB
main-4dbc74f..dule.js gzip 6.14 kB 6.14 kB
webpack-07c5..dule.js gzip 751 B 751 B
677f882d2ed8..dule.js gzip N/A 6.7 kB N/A
Overall change 52.5 kB 52.6 kB ⚠️ +85 B
Legacy Client Bundles (polyfills)
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
polyfills-4b..e242.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
_app-9a0b9e1..b37e.js gzip 1.28 kB 1.28 kB
_error-ed1b0..8fbd.js gzip 3.44 kB 3.44 kB
hooks-89731c..c609.js gzip 887 B 887 B
index-17468f..5d83.js gzip 227 B 227 B
link-d2344ce..8b36.js gzip 1.3 kB 1.3 kB
routerDirect..924c.js gzip 284 B 284 B
withRouter-7..c13d.js gzip 284 B 284 B
Overall change 7.71 kB 7.71 kB
Client Pages Modern
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
_app-75d3a82..dule.js gzip 625 B 625 B
_error-4469a..dule.js gzip 2.29 kB 2.29 kB
hooks-cbf13f..dule.js gzip 387 B 387 B
index-b9a643..dule.js gzip 226 B 226 B
link-f8c0daf..dule.js gzip 1.26 kB 1.26 kB
routerDirect..dule.js gzip 284 B 284 B
withRouter-f..dule.js gzip 282 B 282 B
Overall change 5.36 kB 5.36 kB
Client Build Manifests
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
_buildManifest.js gzip 322 B 322 B
_buildManife..dule.js gzip 329 B 329 B
Overall change 651 B 651 B
Serverless bundles Overall increase ⚠️
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
_error.js 1.03 MB 1.03 MB
404.html 4.22 kB 4.22 kB
hooks.html 3.86 kB 3.86 kB
index.js 1.03 MB 1.03 MB
link.js 1.08 MB 1.08 MB ⚠️ +327 B
routerDirect.js 1.07 MB 1.07 MB ⚠️ +327 B
withRouter.js 1.07 MB 1.07 MB ⚠️ +327 B
Overall change 5.3 MB 5.31 MB ⚠️ +981 B
Commit: a47e2aa

@ijjk

This comment has been minimized.

@ijjk
Copy link
Member Author

ijjk commented Sep 8, 2020

Stats from current PR

Default Server Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
buildDuration 12.1s 12.4s ⚠️ +352ms
nodeModulesSize 56.7 MB 56.7 MB ⚠️ +863 B
Page Load Tests Overall increase ✓
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
/ failed reqs 0 0
/ total time (seconds) 2.146 2.171 ⚠️ +0.02
/ avg req/sec 1165.18 1151.31 ⚠️ -13.87
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.188 1.165 -0.02
/error-in-render avg req/sec 2103.84 2145.98 +42.14
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
677f882d2ed8..a2cc.js gzip 10.8 kB 10.9 kB ⚠️ +109 B
framework.HASH.js gzip 39 kB 39 kB
main-4d826ad..023b.js gzip 7.08 kB 7.08 kB
webpack-e067..f178.js gzip 751 B 751 B
Overall change 57.6 kB 57.7 kB ⚠️ +109 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
677f882d2ed8..dule.js gzip 6.62 kB 6.7 kB ⚠️ +85 B
framework.HA..dule.js gzip 39 kB 39 kB
main-4dbc74f..dule.js gzip 6.14 kB 6.14 kB
webpack-07c5..dule.js gzip 751 B 751 B
Overall change 52.5 kB 52.6 kB ⚠️ +85 B
Legacy Client Bundles (polyfills)
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
polyfills-4b..e242.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
_app-9a0b9e1..b37e.js gzip 1.28 kB 1.28 kB
_error-ed1b0..8fbd.js gzip 3.44 kB 3.44 kB
hooks-89731c..c609.js gzip 887 B 887 B
index-17468f..5d83.js gzip 227 B 227 B
link-d2344ce..8b36.js gzip 1.3 kB 1.3 kB
routerDirect..924c.js gzip 284 B 284 B
withRouter-7..c13d.js gzip 284 B 284 B
Overall change 7.71 kB 7.71 kB
Client Pages Modern
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
_app-75d3a82..dule.js gzip 625 B 625 B
_error-4469a..dule.js gzip 2.29 kB 2.29 kB
hooks-cbf13f..dule.js gzip 387 B 387 B
index-b9a643..dule.js gzip 226 B 226 B
link-f8c0daf..dule.js gzip 1.26 kB 1.26 kB
routerDirect..dule.js gzip 284 B 284 B
withRouter-f..dule.js gzip 282 B 282 B
Overall change 5.36 kB 5.36 kB
Client Build Manifests
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
_buildManifest.js gzip 322 B 322 B
_buildManife..dule.js gzip 329 B 329 B
Overall change 651 B 651 B
Rendered Page Sizes Overall decrease ✓
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
index.html gzip 970 B 968 B -2 B
link.html gzip 977 B 974 B -3 B
withRouter.html gzip 963 B 962 B -1 B
Overall change 2.91 kB 2.9 kB -6 B

Diffs

Diff for 677f882d2ed8..c3c4f674d.js
@@ -867,18 +867,22 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               result = _interpolateAs.result,
               params = _interpolateAs.params;
 
-            interpolatedAs = (0, _utils.formatWithValidation)({
-              pathname: result,
-              hash: finalUrl.hash,
-              query: omitParmsFromQuery(query, params)
-            });
+            if (result) {
+              interpolatedAs = (0, _utils.formatWithValidation)({
+                pathname: result,
+                hash: finalUrl.hash,
+                query: omitParmsFromQuery(query, params)
+              });
+            }
           } // if the origin didn't change, it means we received a relative href
 
           var resolvedHref =
             finalUrl.origin === base.origin
               ? finalUrl.href.slice(finalUrl.origin.length)
               : finalUrl.href;
-          return resolveAs ? [resolvedHref, interpolatedAs] : resolvedHref;
+          return resolveAs
+            ? [resolvedHref, interpolatedAs || resolvedHref]
+            : resolvedHref;
         } catch (_) {
           return resolveAs ? [urlAsString] : urlAsString;
         }
@@ -1331,7 +1335,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             resolvedAs = delBasePath(resolvedAs);
 
                             if (!(0, _isDynamic.isDynamicRoute)(route)) {
-                              _context.next = 47;
+                              _context.next = 54;
                               break;
                             }
 
@@ -1374,33 +1378,56 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             );
 
                           case 44:
-                            _context.next = 47;
+                            _context.next = 54;
                             break;
 
                           case 46:
-                            if (route === asPathname) {
-                              (_interpolateAs2 = interpolateAs(
-                                route,
-                                asPathname,
-                                query
-                              )),
-                                (result = _interpolateAs2.result),
-                                (params = _interpolateAs2.params);
-                              as = (0, _utils.formatWithValidation)(
-                                Object.assign({}, parsedAs, {
-                                  pathname: result,
-                                  query: omitParmsFromQuery(query, params)
-                                })
-                              );
-                            } else {
-                              // Merge params into `query`, overwriting any specified in search
-                              Object.assign(query, routeMatch);
+                            if (!(route === asPathname)) {
+                              _context.next = 53;
+                              break;
+                            }
+
+                            (_interpolateAs2 = interpolateAs(
+                              route,
+                              asPathname,
+                              query
+                            )),
+                              (result = _interpolateAs2.result),
+                              (params = _interpolateAs2.params);
+
+                            if (result) {
+                              _context.next = 50;
+                              break;
                             }
 
-                          case 47:
+                            throw new Error(
+                              "Interpolation failed for href ("
+                                .concat(
+                                  route,
+                                  ") due to not all param values being provided in the query, needed param values ("
+                                )
+                                .concat(params.join(", "), ")\n") +
+                                "Read more: https://err.sh/next.js/href-interpolation-failed"
+                            );
+
+                          case 50:
+                            as = (0, _utils.formatWithValidation)(
+                              Object.assign({}, parsedAs, {
+                                pathname: result,
+                                query: omitParmsFromQuery(query, params)
+                              })
+                            );
+                            _context.next = 54;
+                            break;
+
+                          case 53:
+                            // Merge params into `query`, overwriting any specified in search
+                            Object.assign(query, routeMatch);
+
+                          case 54:
                             Router.events.emit("routeChangeStart", as);
-                            _context.prev = 48;
-                            _context.next = 51;
+                            _context.prev = 55;
+                            _context.next = 58;
                             return this.getRouteInfo(
                               route,
                               pathname,
@@ -1409,7 +1436,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               shallow
                             );
 
-                          case 51:
+                          case 58:
                             routeInfo = _context.sent;
                             (error = routeInfo.error),
                               (props = routeInfo.props),
@@ -1424,7 +1451,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                 props.pageProps.__N_REDIRECT
                               )
                             ) {
-                              _context.next = 62;
+                              _context.next = 69;
                               break;
                             }
 
@@ -1433,7 +1460,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             // it's not
 
                             if (!destination.startsWith("/")) {
-                              _context.next = 60;
+                              _context.next = 67;
                               break;
                             }
 
@@ -1443,7 +1470,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             this._resolveHref(parsedHref, pages);
 
                             if (!pages.includes(parsedHref.pathname)) {
-                              _context.next = 60;
+                              _context.next = 67;
                               break;
                             }
 
@@ -1457,21 +1484,21 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               )
                             );
 
-                          case 60:
+                          case 67:
                             window.location.href = destination;
                             return _context.abrupt(
                               "return",
                               new Promise(function() {})
                             );
 
-                          case 62:
+                          case 69:
                             Router.events.emit("beforeHistoryChange", as);
                             this.changeState(method, url, as, options);
 
                             if (false) {
                             }
 
-                            _context.next = 67;
+                            _context.next = 74;
                             return this.set(
                               route,
                               pathname,
@@ -1483,9 +1510,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               else throw e;
                             });
 
-                          case 67:
+                          case 74:
                             if (!error) {
-                              _context.next = 70;
+                              _context.next = 77;
                               break;
                             }
 
@@ -1496,28 +1523,28 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             );
                             throw error;
 
-                          case 70:
+                          case 77:
                             if (false) {
                             }
 
                             Router.events.emit("routeChangeComplete", as);
                             return _context.abrupt("return", true);
 
-                          case 75:
-                            _context.prev = 75;
-                            _context.t0 = _context["catch"](48);
+                          case 82:
+                            _context.prev = 82;
+                            _context.t0 = _context["catch"](55);
 
                             if (!_context.t0.cancelled) {
-                              _context.next = 79;
+                              _context.next = 86;
                               break;
                             }
 
                             return _context.abrupt("return", false);
 
-                          case 79:
+                          case 86:
                             throw _context.t0;
 
-                          case 80:
+                          case 87:
                           case "end":
                             return _context.stop();
                         }
@@ -1525,7 +1552,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     },
                     _callee,
                     this,
-                    [[48, 75]]
+                    [[55, 82]]
                   );
                 })
               );
Diff for 677f882d2ed8..45.module.js
@@ -720,18 +720,23 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               finalUrl.pathname,
               query
             );
-            interpolatedAs = (0, _utils.formatWithValidation)({
-              pathname: result,
-              hash: finalUrl.hash,
-              query: omitParmsFromQuery(query, params)
-            });
+
+            if (result) {
+              interpolatedAs = (0, _utils.formatWithValidation)({
+                pathname: result,
+                hash: finalUrl.hash,
+                query: omitParmsFromQuery(query, params)
+              });
+            }
           } // if the origin didn't change, it means we received a relative href
 
           var resolvedHref =
             finalUrl.origin === base.origin
               ? finalUrl.href.slice(finalUrl.origin.length)
               : finalUrl.href;
-          return resolveAs ? [resolvedHref, interpolatedAs] : resolvedHref;
+          return resolveAs
+            ? [resolvedHref, interpolatedAs || resolvedHref]
+            : resolvedHref;
         } catch (_) {
           return resolveAs ? [urlAsString] : urlAsString;
         }
@@ -1114,6 +1119,19 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               }
             } else if (route === asPathname) {
               var { result, params } = interpolateAs(route, asPathname, query);
+
+              if (!result) {
+                throw new Error(
+                  "Interpolation failed for href ("
+                    .concat(
+                      route,
+                      ") due to not all param values being provided in the query, needed param values ("
+                    )
+                    .concat(params.join(", "), ")\n") +
+                    "Read more: https://err.sh/next.js/href-interpolation-failed"
+                );
+              }
+
               as = (0, _utils.formatWithValidation)(
                 Object.assign({}, parsedAs, {
                   pathname: result,
Diff for index.html
@@ -25,7 +25,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.7d132ab979d135defe45.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.184bcde6de1f866fd9c5.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -118,13 +118,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.3708ec5b82fc3c4f674d.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.474d66d4231ddfc7d752.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.7d132ab979d135defe45.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.184bcde6de1f866fd9c5.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for link.html
@@ -25,7 +25,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.7d132ab979d135defe45.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.184bcde6de1f866fd9c5.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -123,13 +123,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.3708ec5b82fc3c4f674d.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.474d66d4231ddfc7d752.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.7d132ab979d135defe45.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.184bcde6de1f866fd9c5.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for withRouter.html
@@ -25,7 +25,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.7d132ab979d135defe45.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.184bcde6de1f866fd9c5.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -118,13 +118,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.3708ec5b82fc3c4f674d.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.474d66d4231ddfc7d752.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.7d132ab979d135defe45.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.184bcde6de1f866fd9c5.module.js"
       async=""
       crossorigin="anonymous"
       type="module"

Serverless Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
buildDuration 13.5s 13.8s ⚠️ +278ms
nodeModulesSize 56.7 MB 56.7 MB ⚠️ +863 B
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
677f882d2ed8..a2cc.js gzip 10.8 kB N/A N/A
framework.HASH.js gzip 39 kB 39 kB
main-4d826ad..023b.js gzip 7.08 kB 7.08 kB
webpack-e067..f178.js gzip 751 B 751 B
677f882d2ed8..364e.js gzip N/A 10.9 kB N/A
Overall change 57.6 kB 57.7 kB ⚠️ +109 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
677f882d2ed8..dule.js gzip 6.62 kB N/A N/A
framework.HA..dule.js gzip 39 kB 39 kB
main-4dbc74f..dule.js gzip 6.14 kB 6.14 kB
webpack-07c5..dule.js gzip 751 B 751 B
677f882d2ed8..dule.js gzip N/A 6.7 kB N/A
Overall change 52.5 kB 52.6 kB ⚠️ +85 B
Legacy Client Bundles (polyfills)
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
polyfills-4b..e242.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
_app-9a0b9e1..b37e.js gzip 1.28 kB 1.28 kB
_error-ed1b0..8fbd.js gzip 3.44 kB 3.44 kB
hooks-89731c..c609.js gzip 887 B 887 B
index-17468f..5d83.js gzip 227 B 227 B
link-d2344ce..8b36.js gzip 1.3 kB 1.3 kB
routerDirect..924c.js gzip 284 B 284 B
withRouter-7..c13d.js gzip 284 B 284 B
Overall change 7.71 kB 7.71 kB
Client Pages Modern
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
_app-75d3a82..dule.js gzip 625 B 625 B
_error-4469a..dule.js gzip 2.29 kB 2.29 kB
hooks-cbf13f..dule.js gzip 387 B 387 B
index-b9a643..dule.js gzip 226 B 226 B
link-f8c0daf..dule.js gzip 1.26 kB 1.26 kB
routerDirect..dule.js gzip 284 B 284 B
withRouter-f..dule.js gzip 282 B 282 B
Overall change 5.36 kB 5.36 kB
Client Build Manifests
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
_buildManifest.js gzip 322 B 322 B
_buildManife..dule.js gzip 329 B 329 B
Overall change 651 B 651 B
Serverless bundles Overall increase ⚠️
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
_error.js 1.03 MB 1.03 MB
404.html 4.22 kB 4.22 kB
hooks.html 3.86 kB 3.86 kB
index.js 1.03 MB 1.03 MB
link.js 1.08 MB 1.08 MB ⚠️ +327 B
routerDirect.js 1.07 MB 1.07 MB ⚠️ +327 B
withRouter.js 1.07 MB 1.07 MB ⚠️ +327 B
Overall change 5.3 MB 5.31 MB ⚠️ +981 B
Commit: 4ffa152

Copy link
Member

@Timer Timer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I swear we already have a similar check for this elsewhere and I think we're duplicating logic.

Edit: as yes, right above the error we just added. Can we consolidate these two somehow?

@ijjk
Copy link
Member Author

ijjk commented Sep 10, 2020

Stats from current PR

Default Server Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
buildDuration 12.8s 12.5s -296ms
nodeModulesSize 57 MB 57 MB ⚠️ +1.49 kB
Page Load Tests Overall increase ✓
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
/ failed reqs 0 0
/ total time (seconds) 2.35 2.29 -0.06
/ avg req/sec 1063.77 1091.92 +28.15
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.366 1.324 -0.04
/error-in-render avg req/sec 1829.89 1888.69 +58.8
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
677f882d2ed8..4c1a.js gzip 10.8 kB 10.9 kB ⚠️ +90 B
framework.HASH.js gzip 39 kB 39 kB
main-18c9b45..05ea.js gzip 7 kB 7 kB
webpack-e067..f178.js gzip 751 B 751 B
Overall change 57.5 kB 57.6 kB ⚠️ +90 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
677f882d2ed8..dule.js gzip 6.67 kB 6.77 kB ⚠️ +95 B
framework.HA..dule.js gzip 39 kB 39 kB
main-3e4ebe7..dule.js gzip 6.07 kB 6.07 kB
webpack-07c5..dule.js gzip 751 B 751 B
Overall change 52.5 kB 52.6 kB ⚠️ +95 B
Legacy Client Bundles (polyfills)
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
polyfills-4b..e242.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
_app-9a0b9e1..b37e.js gzip 1.28 kB 1.28 kB
_error-ed1b0..8fbd.js gzip 3.44 kB 3.44 kB
hooks-89731c..c609.js gzip 887 B 887 B
index-17468f..5d83.js gzip 227 B 227 B
link-d2344ce..8b36.js gzip 1.3 kB 1.3 kB
routerDirect..924c.js gzip 284 B 284 B
withRouter-7..c13d.js gzip 284 B 284 B
Overall change 7.71 kB 7.71 kB
Client Pages Modern
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
_app-75d3a82..dule.js gzip 625 B 625 B
_error-4469a..dule.js gzip 2.29 kB 2.29 kB
hooks-cbf13f..dule.js gzip 387 B 387 B
index-b9a643..dule.js gzip 226 B 226 B
link-f8c0daf..dule.js gzip 1.26 kB 1.26 kB
routerDirect..dule.js gzip 284 B 284 B
withRouter-f..dule.js gzip 282 B 282 B
Overall change 5.36 kB 5.36 kB
Client Build Manifests
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
_buildManifest.js gzip 322 B 322 B
_buildManife..dule.js gzip 329 B 329 B
Overall change 651 B 651 B
Rendered Page Sizes Overall increase ⚠️
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
index.html gzip 1 kB 1 kB ⚠️ +1 B
link.html gzip 1.01 kB 1.01 kB ⚠️ +2 B
withRouter.html gzip 993 B 995 B ⚠️ +2 B
Overall change 3 kB 3.01 kB ⚠️ +5 B

Diffs

Diff for 677f882d2ed8..7d.module.js
@@ -734,18 +734,23 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               finalUrl.pathname,
               query
             );
-            interpolatedAs = (0, _utils.formatWithValidation)({
-              pathname: result,
-              hash: finalUrl.hash,
-              query: omitParmsFromQuery(query, params)
-            });
+
+            if (result) {
+              interpolatedAs = (0, _utils.formatWithValidation)({
+                pathname: result,
+                hash: finalUrl.hash,
+                query: omitParmsFromQuery(query, params)
+              });
+            }
           } // if the origin didn't change, it means we received a relative href
 
           var resolvedHref =
             finalUrl.origin === base.origin
               ? finalUrl.href.slice(finalUrl.origin.length)
               : finalUrl.href;
-          return resolveAs ? [resolvedHref, interpolatedAs] : resolvedHref;
+          return resolveAs
+            ? [resolvedHref, interpolatedAs || resolvedHref]
+            : resolvedHref;
         } catch (_) {
           return resolveAs ? [urlAsString] : urlAsString;
         }
@@ -1107,8 +1112,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             var routeMatch = (0, _routeMatcher.getRouteMatcher)(routeRegex)(
               asPathname
             );
+            var shouldInterpolate = route === asPathname;
+            var interpolatedAs = shouldInterpolate
+              ? interpolateAs(route, asPathname, query)
+              : {};
 
-            if (!routeMatch) {
+            if (!routeMatch || (shouldInterpolate && !interpolatedAs.result)) {
               var missingParams = Object.keys(routeRegex.groups).filter(
                 param => !query[param]
               );
@@ -1118,21 +1127,31 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                 }
 
                 throw new Error(
-                  "The provided `as` value ("
-                    .concat(
-                      asPathname,
-                      ") is incompatible with the `href` value ("
+                  (shouldInterpolate
+                    ? "The provided `href` ("
+                        .concat(url, ") value is missing query values (")
+                        .concat(
+                          missingParams.join(", "),
+                          ") to be interpolated properly. "
+                        )
+                    : "The provided `as` value ("
+                        .concat(
+                          asPathname,
+                          ") is incompatible with the `href` value ("
+                        )
+                        .concat(route, "). ")) +
+                    "Read more: https://err.sh/vercel/next.js/".concat(
+                      shouldInterpolate
+                        ? "href-interpolation-failed"
+                        : "incompatible-href-as"
                     )
-                    .concat(route, "). ") +
-                    "Read more: https://err.sh/vercel/next.js/incompatible-href-as"
                 );
               }
-            } else if (route === asPathname) {
-              var { result, params } = interpolateAs(route, asPathname, query);
+            } else if (shouldInterpolate) {
               as = (0, _utils.formatWithValidation)(
                 Object.assign({}, parsedAs, {
-                  pathname: result,
-                  query: omitParmsFromQuery(query, params)
+                  pathname: interpolatedAs.result,
+                  query: omitParmsFromQuery(query, interpolatedAs.params)
                 })
               );
             } else {
Diff for 677f882d2ed8..84ee646d4.js
@@ -879,18 +879,22 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               result = _interpolateAs.result,
               params = _interpolateAs.params;
 
-            interpolatedAs = (0, _utils.formatWithValidation)({
-              pathname: result,
-              hash: finalUrl.hash,
-              query: omitParmsFromQuery(query, params)
-            });
+            if (result) {
+              interpolatedAs = (0, _utils.formatWithValidation)({
+                pathname: result,
+                hash: finalUrl.hash,
+                query: omitParmsFromQuery(query, params)
+              });
+            }
           } // if the origin didn't change, it means we received a relative href
 
           var resolvedHref =
             finalUrl.origin === base.origin
               ? finalUrl.href.slice(finalUrl.origin.length)
               : finalUrl.href;
-          return resolveAs ? [resolvedHref, interpolatedAs] : resolvedHref;
+          return resolveAs
+            ? [resolvedHref, interpolatedAs || resolvedHref]
+            : resolvedHref;
         } catch (_) {
           return resolveAs ? [urlAsString] : urlAsString;
         }
@@ -1221,10 +1225,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     asPathname,
                     routeRegex,
                     routeMatch,
+                    shouldInterpolate,
+                    interpolatedAs,
                     missingParams,
-                    _interpolateAs2,
-                    result,
-                    params,
                     routeInfo,
                     error,
                     props,
@@ -1344,7 +1347,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             resolvedAs = delBasePath(resolvedAs);
 
                             if (!(0, _isDynamic.isDynamicRoute)(route)) {
-                              _context.next = 47;
+                              _context.next = 49;
                               break;
                             }
 
@@ -1356,9 +1359,18 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             routeMatch = (0, _routeMatcher.getRouteMatcher)(
                               routeRegex
                             )(asPathname);
+                            shouldInterpolate = route === asPathname;
+                            interpolatedAs = shouldInterpolate
+                              ? interpolateAs(route, asPathname, query)
+                              : {};
 
-                            if (routeMatch) {
-                              _context.next = 46;
+                            if (
+                              !(
+                                !routeMatch ||
+                                (shouldInterpolate && !interpolatedAs.result)
+                              )
+                            ) {
+                              _context.next = 48;
                               break;
                             }
 
@@ -1369,7 +1381,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             });
 
                             if (!(missingParams.length > 0)) {
-                              _context.next = 44;
+                              _context.next = 46;
                               break;
                             }
 
@@ -1377,32 +1389,42 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             }
 
                             throw new Error(
-                              "The provided `as` value ("
-                                .concat(
-                                  asPathname,
-                                  ") is incompatible with the `href` value ("
+                              (shouldInterpolate
+                                ? "The provided `href` ("
+                                    .concat(
+                                      url,
+                                      ") value is missing query values ("
+                                    )
+                                    .concat(
+                                      missingParams.join(", "),
+                                      ") to be interpolated properly. "
+                                    )
+                                : "The provided `as` value ("
+                                    .concat(
+                                      asPathname,
+                                      ") is incompatible with the `href` value ("
+                                    )
+                                    .concat(route, "). ")) +
+                                "Read more: https://err.sh/vercel/next.js/".concat(
+                                  shouldInterpolate
+                                    ? "href-interpolation-failed"
+                                    : "incompatible-href-as"
                                 )
-                                .concat(route, "). ") +
-                                "Read more: https://err.sh/vercel/next.js/incompatible-href-as"
                             );
 
-                          case 44:
-                            _context.next = 47;
+                          case 46:
+                            _context.next = 49;
                             break;
 
-                          case 46:
-                            if (route === asPathname) {
-                              (_interpolateAs2 = interpolateAs(
-                                route,
-                                asPathname,
-                                query
-                              )),
-                                (result = _interpolateAs2.result),
-                                (params = _interpolateAs2.params);
+                          case 48:
+                            if (shouldInterpolate) {
                               as = (0, _utils.formatWithValidation)(
                                 Object.assign({}, parsedAs, {
-                                  pathname: result,
-                                  query: omitParmsFromQuery(query, params)
+                                  pathname: interpolatedAs.result,
+                                  query: omitParmsFromQuery(
+                                    query,
+                                    interpolatedAs.params
+                                  )
                                 })
                               );
                             } else {
@@ -1410,10 +1432,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               Object.assign(query, routeMatch);
                             }
 
-                          case 47:
+                          case 49:
                             Router.events.emit("routeChangeStart", as);
-                            _context.prev = 48;
-                            _context.next = 51;
+                            _context.prev = 50;
+                            _context.next = 53;
                             return this.getRouteInfo(
                               route,
                               pathname,
@@ -1422,7 +1444,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               shallow
                             );
 
-                          case 51:
+                          case 53:
                             routeInfo = _context.sent;
                             (error = routeInfo.error),
                               (props = routeInfo.props),
@@ -1437,7 +1459,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                 props.pageProps.__N_REDIRECT
                               )
                             ) {
-                              _context.next = 62;
+                              _context.next = 64;
                               break;
                             }
 
@@ -1446,7 +1468,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             // it's not
 
                             if (!destination.startsWith("/")) {
-                              _context.next = 60;
+                              _context.next = 62;
                               break;
                             }
 
@@ -1456,7 +1478,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             this._resolveHref(parsedHref, pages);
 
                             if (!pages.includes(parsedHref.pathname)) {
-                              _context.next = 60;
+                              _context.next = 62;
                               break;
                             }
 
@@ -1470,21 +1492,21 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               )
                             );
 
-                          case 60:
+                          case 62:
                             window.location.href = destination;
                             return _context.abrupt(
                               "return",
                               new Promise(function() {})
                             );
 
-                          case 62:
+                          case 64:
                             Router.events.emit("beforeHistoryChange", as);
                             this.changeState(method, url, as, options);
 
                             if (false) {
                             }
 
-                            _context.next = 67;
+                            _context.next = 69;
                             return this.set(
                               route,
                               pathname,
@@ -1496,9 +1518,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               else throw e;
                             });
 
-                          case 67:
+                          case 69:
                             if (!error) {
-                              _context.next = 70;
+                              _context.next = 72;
                               break;
                             }
 
@@ -1509,28 +1531,28 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             );
                             throw error;
 
-                          case 70:
+                          case 72:
                             if (false) {
                             }
 
                             Router.events.emit("routeChangeComplete", as);
                             return _context.abrupt("return", true);
 
-                          case 75:
-                            _context.prev = 75;
-                            _context.t0 = _context["catch"](48);
+                          case 77:
+                            _context.prev = 77;
+                            _context.t0 = _context["catch"](50);
 
                             if (!_context.t0.cancelled) {
-                              _context.next = 79;
+                              _context.next = 81;
                               break;
                             }
 
                             return _context.abrupt("return", false);
 
-                          case 79:
+                          case 81:
                             throw _context.t0;
 
-                          case 80:
+                          case 82:
                           case "end":
                             return _context.stop();
                         }
@@ -1538,7 +1560,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     },
                     _callee,
                     this,
-                    [[48, 75]]
+                    [[50, 77]]
                   );
                 })
               );
Diff for index.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.2f81f282125bd1f09d7d.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.7baf55f93a067e35adbc.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -121,13 +121,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.aedf4c7133284ee646d4.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.1294f190dde0f9421be3.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.2f81f282125bd1f09d7d.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.7baf55f93a067e35adbc.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for link.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.2f81f282125bd1f09d7d.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.7baf55f93a067e35adbc.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -126,13 +126,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.aedf4c7133284ee646d4.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.1294f190dde0f9421be3.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.2f81f282125bd1f09d7d.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.7baf55f93a067e35adbc.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for withRouter.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.2f81f282125bd1f09d7d.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.7baf55f93a067e35adbc.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -121,13 +121,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.aedf4c7133284ee646d4.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.1294f190dde0f9421be3.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.2f81f282125bd1f09d7d.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.7baf55f93a067e35adbc.module.js"
       async=""
       crossorigin="anonymous"
       type="module"

Serverless Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
buildDuration 14.4s 14.2s -179ms
nodeModulesSize 57 MB 57 MB ⚠️ +1.49 kB
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
677f882d2ed8..4c1a.js gzip 10.8 kB N/A N/A
framework.HASH.js gzip 39 kB 39 kB
main-18c9b45..05ea.js gzip 7 kB 7 kB
webpack-e067..f178.js gzip 751 B 751 B
677f882d2ed8..68c9.js gzip N/A 10.9 kB N/A
Overall change 57.5 kB 57.6 kB ⚠️ +90 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
677f882d2ed8..dule.js gzip 6.67 kB N/A N/A
framework.HA..dule.js gzip 39 kB 39 kB
main-3e4ebe7..dule.js gzip 6.07 kB 6.07 kB
webpack-07c5..dule.js gzip 751 B 751 B
677f882d2ed8..dule.js gzip N/A 6.77 kB N/A
Overall change 52.5 kB 52.6 kB ⚠️ +95 B
Legacy Client Bundles (polyfills)
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
polyfills-4b..e242.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
_app-9a0b9e1..b37e.js gzip 1.28 kB 1.28 kB
_error-ed1b0..8fbd.js gzip 3.44 kB 3.44 kB
hooks-89731c..c609.js gzip 887 B 887 B
index-17468f..5d83.js gzip 227 B 227 B
link-d2344ce..8b36.js gzip 1.3 kB 1.3 kB
routerDirect..924c.js gzip 284 B 284 B
withRouter-7..c13d.js gzip 284 B 284 B
Overall change 7.71 kB 7.71 kB
Client Pages Modern
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
_app-75d3a82..dule.js gzip 625 B 625 B
_error-4469a..dule.js gzip 2.29 kB 2.29 kB
hooks-cbf13f..dule.js gzip 387 B 387 B
index-b9a643..dule.js gzip 226 B 226 B
link-f8c0daf..dule.js gzip 1.26 kB 1.26 kB
routerDirect..dule.js gzip 284 B 284 B
withRouter-f..dule.js gzip 282 B 282 B
Overall change 5.36 kB 5.36 kB
Client Build Manifests
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
_buildManifest.js gzip 322 B 322 B
_buildManife..dule.js gzip 329 B 329 B
Overall change 651 B 651 B
Serverless bundles Overall increase ⚠️
vercel/next.js canary ijjk/next.js error/invalid-interpolation Change
_error.js 1.03 MB 1.03 MB
404.html 4.34 kB 4.34 kB
hooks.html 3.92 kB 3.92 kB
index.js 1.04 MB 1.04 MB
link.js 1.08 MB 1.08 MB ⚠️ +376 B
routerDirect.js 1.07 MB 1.07 MB ⚠️ +376 B
withRouter.js 1.07 MB 1.07 MB ⚠️ +376 B
Overall change 5.31 MB 5.31 MB ⚠️ +1.13 kB
Commit: 307bd32

@ijjk ijjk requested a review from Timer September 10, 2020 20:03
Copy link
Member

@Timer Timer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@kodiakhq kodiakhq bot merged commit 47d983f into vercel:canary Sep 10, 2020
@ijjk ijjk deleted the error/invalid-interpolation branch September 10, 2020 20:05
HitoriSensei pushed a commit to HitoriSensei/next.js that referenced this pull request Sep 26, 2020
This adds an error when interpolation fails to make sure invalid `href`s aren't accidentally used and an invalid URL is built. 

Closes: vercel#16944
@vercel vercel locked as resolved and limited conversation to collaborators Jan 29, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

When href interpolation fails we should error properly
2 participants