-
Notifications
You must be signed in to change notification settings - Fork 143
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
[Themes] Add error overlay for theme upload failures #5208
base: jm/01-15-unify_asset_upload_error_reporting
Are you sure you want to change the base?
[Themes] Add error overlay for theme upload failures #5208
Conversation
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
Coverage report
Show files with reduced coverage 🔻
Test suite run success2007 tests passing in 906 suites. Report generated by 🧪jest coverage report action from c720fc6 |
296bee3
to
5c60ebd
Compare
We detected some changes at packages/*/src and there are no updates in the .changeset. |
5c60ebd
to
d659886
Compare
} else { | ||
const errors = result?.errors?.asset ?? ['Response was not successful.'] | ||
uploadErrors.set(fileKey, errors) | ||
throw new Error(errors.length === 1 ? errors[0] : errors.join('\n')) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we want to keep throwing the error here so that we output to the terminal.
d659886
to
4ba80de
Compare
/** | ||
* Stores upload errors returned when uploading files via the Asset API | ||
*/ | ||
uploadErrors: Map<Key, string[]> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I considered storing this inside of the ThemeAsset
type
I chose to store it here because
- This type is simple, easy to update, and communicates that this is a temporary store of errors rather than an actual property of the theme asset
- It is likely that we will update this and check if this is empty frequently. We want these operations to be fast and straightforward
- Checking whether uploadErrors are present is be O(1) since we don't need to read all theme assets
- We COULD do a two-pronged approach where we store a list of files with errors in a
Set
, and store the errors themselves on theThemeAsset
. I tried this and it felt clunky.
- We COULD do a two-pronged approach where we store a list of files with errors in a
- Updates should be fast and easy
- If we store in
ThemeAsset
, we'd need to get the asset, check if it exists, and update theerror
key
- If we store in
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Conceptually I love this. Let's see if we can put a little polish on it!
} else { | ||
const errors = result?.errors?.asset ?? ['Response was not successful.'] | ||
uploadErrors.set(fileKey, errors) | ||
throw new Error(errors.length === 1 ? errors[0] : errors.join('\n')) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
throw new Error(errors.length === 1 ? errors[0] : errors.join('\n')) | |
throw new Error(errors.join('\n')) |
> ['foo'].join(',')
'foo'
.join('') | ||
|
||
return ` | ||
<div id="section-error-overlay" style="${OVERLAY_STYLES.container}"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would prefer to use something like the dialog
element so that we don't need to manually roll a bunch of accessibility features: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog
} | ||
|
||
export function injectErrorIntoHtml(html: string, errors: Map<string, string[]>): string { | ||
return html + getErrorOverlay(errors) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I had an error and then another error would this end up rendering multiple overlays?
|
||
// Then | ||
const overlay = getErrorOverlay(errors) | ||
expect(result).toBe(html + overlay) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤔 would this imply that our overlay is rendering after the closing </html>
tag? If so let's make sure we're rendering inside of the document.
@@ -0,0 +1,74 @@ | |||
const OVERLAY_STYLES = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a few opinions on the styling here but let's settle on implementation before tweaking a bunch of this!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@graygilmore let's pair on this tommorow! Some of your questions will be resolved in the stack above this.
This PR is definitely the place to talk about styling / the overlay itself, so thanks for raising that!
Differences in type declarationsWe detected differences in the type declarations generated by Typescript for this branch compared to the baseline ('main' branch). Please, review them to ensure they are backward-compatible. Here are some important things to keep in mind:
New type declarationsWe found no new type declarations in this PR Existing type declarationspackages/cli-kit/dist/private/node/constants.d.ts@@ -31,6 +31,7 @@ export declare const environmentVariables: {
otelURL: string;
themeKitAccessDomain: string;
json: string;
+ useAppManagement: string;
};
export declare const defaultThemeKitAccessDomain = "theme-kit-access.shopifyapps.com";
export declare const systemEnvironmentVariables: {
packages/cli-kit/dist/private/node/api/headers.d.ts@@ -1,6 +1,6 @@
import { ExtendableError } from '../../../public/node/error.js';
import https from 'https';
-declare class RequestClientError extends ExtendableError {
+export declare class RequestClientError extends ExtendableError {
statusCode: number;
constructor(message: string, statusCode: number);
}
@@ -25,5 +25,4 @@ export declare function buildHeaders(token?: string): {
* if the service is running in a Spin environment, the attribute "rejectUnauthorized" is
* set to false
*/
-export declare function httpsAgent(): Promise<https.Agent>;
-export {};
\ No newline at end of file
+export declare function httpsAgent(): Promise<https.Agent>;
\ No newline at end of file
packages/cli-kit/dist/private/node/session/scopes.d.ts@@ -5,7 +5,7 @@ import { API } from '../api.js';
* @param extraScopes - custom user-defined scopes
* @returns Array of scopes
*/
-export declare function allDefaultScopes(extraScopes?: string[]): string[];
+export declare function allDefaultScopes(extraScopes?: string[], systemEnvironment?: NodeJS.ProcessEnv): string[];
/**
* Generate a flat array with the default scopes for the given API plus
* any custom scope defined by the user
@@ -13,4 +13,4 @@ export declare function allDefaultScopes(extraScopes?: string[]): string[];
* @param extraScopes - custom user-defined scopes
* @returns Array of scopes
*/
-export declare function apiScopes(api: API, extraScopes?: string[]): string[];
\ No newline at end of file
+export declare function apiScopes(api: API, extraScopes?: string[], systemEnvironment?: NodeJS.ProcessEnv): string[];
\ No newline at end of file
packages/cli-kit/dist/public/node/context/local.d.ts@@ -26,12 +26,12 @@ export declare function isDevelopment(env?: NodeJS.ProcessEnv): boolean;
*/
export declare function isVerbose(env?: NodeJS.ProcessEnv): boolean;
/**
- * It returns true if the App Management API is disabled.
- * This should only be relevant when using a Partners token.
+ * It returns true if the App Management API is available.
*
- * @returns True if the App Management API is disabled.
+ * @param env - The environment variables from the environment of the current process.
+ * @returns True if the App Management API is available.
*/
-export declare function isAppManagementDisabled(): boolean;
+export declare function isAppManagementEnabled(env?: NodeJS.ProcessEnv): boolean;
/**
* Returns true if the environment in which the CLI is running is either
* a local environment (where dev is present) or a cloud environment (spin).
packages/cli-kit/dist/public/node/themes/types.d.ts@@ -92,6 +92,10 @@ export interface ThemeFileSystem extends VirtualFileSystem {
applyIgnoreFilters: <T extends {
key: string;
}>(files: T[]) => T[];
+ /**
+ * Stores upload errors returned when uploading files via the Asset API
+ */
+ uploadErrors: Map<Key, string[]>;
}
/**
* Represents a theme on the file system.
|
c720fc6
to
97f475a
Compare
454ca51
to
0971b54
Compare
WHY are these changes introduced?
Provide a visual indicator in the rendered development host server when asset upload errors occur. This can make it easier to spot / identify when you live theme may differ from what
theme dev
is serving.In the
theme dev
proxy server, we directly serve asset values to SFR while waiting for upload of the file. This means that may still render content that is actually not being saved to the remote theme - this can be confusing, and currently the only indicator of this is in the terminal)WHAT is this pull request doing?
Adds an error overlay system that displays theme development errors in the browser. This PR only renders NEW errors you introduce while the
theme dev
server is running.The following PR in this stack will include the initial theme upload results in the overlay.
I want this PR to focus on the overlay itself / how we are storing the data.
How to test your changes?
Measuring impact
Checklist