fix: Fall of the error toasts wall (#35839)
This commit is contained in:
parent
5aa93926ef
commit
65eb8546f4
|
|
@ -238,7 +238,7 @@ describe("storeValue Action test", { tags: ["@tag.JS"] }, () => {
|
|||
});
|
||||
agHelper.ClickButton("Test store logs");
|
||||
|
||||
debuggerHelper.ClickDebuggerIcon();
|
||||
debuggerHelper.OpenDebugger();
|
||||
debuggerHelper.ClickLogsTab();
|
||||
debuggerHelper.changeLogsGroup("System logs");
|
||||
debuggerHelper.DoesConsoleLogExist("storeValue('xyz', '123', true)");
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import {
|
|||
draggableWidgets,
|
||||
fakerHelper,
|
||||
dataManager,
|
||||
debuggerHelper,
|
||||
} from "../../../../support/Objects/ObjectsCore";
|
||||
|
||||
const widgetsToTest = {
|
||||
|
|
@ -180,8 +181,18 @@ Object.entries(widgetsToTest).forEach(([widgetSelector, testConfig], index) => {
|
|||
agHelper.GetNClick(locators._widgetInputSelector(widgetSelector));
|
||||
agHelper.PressDelete();
|
||||
|
||||
//Since widget is removed & Button is still holding its reference
|
||||
debuggerHelper.AssertDebugError(
|
||||
`'${testConfig.widgetPrefixName}1' is not defined.`,
|
||||
"",
|
||||
true,
|
||||
false,
|
||||
);
|
||||
debuggerHelper.CloseBottomBar();
|
||||
agHelper.GetNClick(getWidgetSelector(draggableWidgets.BUTTON));
|
||||
agHelper.AssertContains("is not defined"); //Since widget is removed & Button is still holding its reference
|
||||
agHelper.ValidateToastMessage(
|
||||
`${testConfig.widgetPrefixName}1 is not defined`,
|
||||
);
|
||||
agHelper.PressDelete();
|
||||
|
||||
agHelper.GetNClick(getWidgetSelector(draggableWidgets.TEXT)).click();
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ describe(
|
|||
deployMode.NavigateBacktoEditor();
|
||||
|
||||
//verify runAstros triggered on PageLaoad of Edit page!
|
||||
debuggerHelper.ClickDebuggerIcon();
|
||||
debuggerHelper.OpenDebugger();
|
||||
debuggerHelper.ClickLogsTab();
|
||||
debuggerHelper.DebuggerLogsFilter("JSObject1.runAstros");
|
||||
debuggerHelper.DoesConsoleLogExist("JS Function executed successfully");
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ describe(
|
|||
apiPage.EnterHeader("test", "test");
|
||||
debuggerHelper.AssertErrorCount(1);
|
||||
EditorNavigation.ShowCanvas();
|
||||
debuggerHelper.ClickDebuggerIcon();
|
||||
debuggerHelper.OpenDebugger();
|
||||
debuggerHelper.ClicklogEntityLink();
|
||||
|
||||
agHelper.AssertElementVisibility(apiPage._nextCursorValue);
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ describe("JSObjects", () => {
|
|||
shouldCreateNewJSObj: true,
|
||||
});
|
||||
|
||||
debuggerHelper.ClickDebuggerIcon();
|
||||
debuggerHelper.OpenDebugger();
|
||||
debuggerHelper.ClicklogEntityLink();
|
||||
agHelper.AssertCursorInput(".js-editor", { ch: 20, line: 6 });
|
||||
|
||||
|
|
|
|||
|
|
@ -66,8 +66,7 @@ describe(
|
|||
);
|
||||
debuggerHelper.AssertErrorCount(2);
|
||||
|
||||
debuggerHelper.ClickDebuggerIcon();
|
||||
debuggerHelper.ClicklogEntityLink();
|
||||
debuggerHelper.OpenDebugger();
|
||||
agHelper.AssertElementVisibility(
|
||||
".t--actionConfiguration\\.formData\\.limitDocuments\\.data",
|
||||
);
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ describe(
|
|||
_.debuggerHelper.AssertErrorCount(1);
|
||||
_.propPane.ToggleSection("general");
|
||||
_.agHelper.AssertElementAbsence("animateloading");
|
||||
_.debuggerHelper.ClickDebuggerIcon();
|
||||
_.debuggerHelper.OpenDebugger();
|
||||
_.debuggerHelper.ClicklogEntityLink();
|
||||
_.propPane.AssertIfPropertyIsVisible("animateloading");
|
||||
|
||||
|
|
@ -28,7 +28,7 @@ describe(
|
|||
_.propPane.EnterJSContext("visible", "{{test}}", true, false);
|
||||
_.debuggerHelper.AssertErrorCount(1);
|
||||
_.propPane.NavigateBackToPropertyPane();
|
||||
_.debuggerHelper.ClickDebuggerIcon();
|
||||
_.debuggerHelper.OpenDebugger();
|
||||
_.debuggerHelper.ClicklogEntityLink();
|
||||
_.agHelper.GetNAssertContains(_.propPane._paneTitle, "Tab 2");
|
||||
_.propPane.AssertIfPropertyIsVisible("visible");
|
||||
|
|
@ -48,7 +48,7 @@ describe(
|
|||
_.debuggerHelper.AssertErrorCount(1);
|
||||
_.propPane.NavigateBackToPropertyPane(false);
|
||||
_.propPane.NavigateBackToPropertyPane();
|
||||
_.debuggerHelper.ClickDebuggerIcon();
|
||||
_.debuggerHelper.OpenDebugger();
|
||||
_.debuggerHelper.ClicklogEntityLink();
|
||||
_.agHelper.GetNAssertContains(_.propPane._paneTitle, "Menu Item");
|
||||
_.propPane.AssertIfPropertyIsVisible("icon");
|
||||
|
|
@ -65,7 +65,7 @@ describe(
|
|||
_.propPane.MoveToTab("Style");
|
||||
_.debuggerHelper.AssertErrorCount(1);
|
||||
_.propPane.NavigateBackToPropertyPane();
|
||||
_.debuggerHelper.ClickDebuggerIcon();
|
||||
_.debuggerHelper.OpenDebugger();
|
||||
_.debuggerHelper.ClicklogEntityLink();
|
||||
_.agHelper.GetNAssertContains(_.propPane._paneTitle, "Second Menu Item");
|
||||
_.propPane.AssertIfPropertyIsVisible("disabled");
|
||||
|
|
@ -110,7 +110,7 @@ describe(
|
|||
_.propPane.NavigateBackToPropertyPane(false);
|
||||
_.propPane.NavigateBackToPropertyPane();
|
||||
|
||||
_.debuggerHelper.ClickDebuggerIcon();
|
||||
_.debuggerHelper.OpenDebugger();
|
||||
_.debuggerHelper.ClicklogEntityLink();
|
||||
_.agHelper.GetNAssertContains(_.propPane._paneTitle, "Custom Field 2");
|
||||
_.propPane.AssertIfPropertyIsVisible("borderradius");
|
||||
|
|
@ -133,7 +133,7 @@ describe(
|
|||
_.propPane.EnterJSContext("disabled", "{{test}}", true, false);
|
||||
_.debuggerHelper.AssertErrorCount(2);
|
||||
|
||||
_.debuggerHelper.ClickDebuggerIcon();
|
||||
_.debuggerHelper.OpenDebugger();
|
||||
_.debuggerHelper.ClicklogEntityLink(true);
|
||||
_.agHelper.GetNAssertContains(_.propPane._paneTitle, "First Menu Item");
|
||||
_.debuggerHelper.CloseBottomBar();
|
||||
|
|
@ -173,7 +173,7 @@ describe(
|
|||
_.propPane.ToggleSection("validation");
|
||||
_.propPane.NavigateBackToPropertyPane();
|
||||
|
||||
_.debuggerHelper.ClickDebuggerIcon();
|
||||
_.debuggerHelper.OpenDebugger();
|
||||
_.debuggerHelper.ClicklogEntityLink();
|
||||
_.agHelper.GetNAssertContains(_.propPane._paneTitle, "imdb_id");
|
||||
_.debuggerHelper.CloseBottomBar();
|
||||
|
|
|
|||
|
|
@ -3,9 +3,6 @@ import EditorNavigation, {
|
|||
EntityType,
|
||||
} from "../../../../support/Pages/EditorNavigation";
|
||||
import PageList from "../../../../support/Pages/PageList";
|
||||
const locators = {
|
||||
errorPageTitle: ".t--error-page-title",
|
||||
};
|
||||
|
||||
describe("Pages", { tags: ["@tag.IDE"] }, function () {
|
||||
let veryLongPageName = `abcdefghijklmnopqrstuvwxyz1234`;
|
||||
|
|
@ -36,7 +33,7 @@ describe("Pages", { tags: ["@tag.IDE"] }, function () {
|
|||
EditorNavigation.SelectEntityByName("Page1 Copy", EntityType.Page);
|
||||
//Checks if 404 is showing correct route
|
||||
cy.visit("/route-that-does-not-exist");
|
||||
cy.get(locators.errorPageTitle).should(($x) => {
|
||||
cy.get(_.locators.errorPageTitle).should(($x) => {
|
||||
expect($x).contain(Cypress.env("MESSAGES").PAGE_NOT_FOUND());
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ describe("Entity bottom bar", { tags: ["@tag.IDE"] }, () => {
|
|||
//Verify if bottom bar is closed.
|
||||
_.debuggerHelper.AssertClosed();
|
||||
//verify if bottom bar is open on clicking debugger icon in canvas.
|
||||
_.debuggerHelper.ClickDebuggerIcon();
|
||||
_.debuggerHelper.OpenDebugger();
|
||||
_.debuggerHelper.AssertOpen(PageType.Canvas);
|
||||
//Verify if selected tab is errors in tab title.
|
||||
_.debuggerHelper.AssertSelectedTab(
|
||||
|
|
@ -48,7 +48,7 @@ describe("Entity bottom bar", { tags: ["@tag.IDE"] }, () => {
|
|||
//Verify that the errors tab is still closed.
|
||||
_.debuggerHelper.AssertClosed();
|
||||
//Verify if bottom bar opens on clicking debugger icon in api page.
|
||||
_.debuggerHelper.ClickDebuggerIcon();
|
||||
_.debuggerHelper.OpenDebugger();
|
||||
_.debuggerHelper.AssertOpen(PageType.API);
|
||||
//Verify if selected tab is errors in tab title.
|
||||
_.debuggerHelper.AssertSelectedTab(
|
||||
|
|
@ -70,7 +70,7 @@ describe("Entity bottom bar", { tags: ["@tag.IDE"] }, () => {
|
|||
//Expecting errors tab to be closed as this is now a datasource
|
||||
_.debuggerHelper.AssertClosed();
|
||||
//Verify if bottom bar opens on clicking debugger icon in datasource page.
|
||||
_.debuggerHelper.ClickDebuggerIcon();
|
||||
_.debuggerHelper.OpenDebugger();
|
||||
_.debuggerHelper.AssertOpen(PageType.DataSources);
|
||||
});
|
||||
|
||||
|
|
@ -91,7 +91,7 @@ describe("Entity bottom bar", { tags: ["@tag.IDE"] }, () => {
|
|||
_.debuggerHelper.AssertClosed();
|
||||
//Verify if bottom bar opens on clicking debugger icon in query page.
|
||||
_.dataSources.CreateQueryAfterDSSaved();
|
||||
_.debuggerHelper.ClickDebuggerIcon();
|
||||
_.debuggerHelper.OpenDebugger();
|
||||
_.debuggerHelper.AssertOpen(PageType.Query);
|
||||
//Verify if bottom bar is closed on clicking close icon in query page.
|
||||
_.debuggerHelper.CloseBottomBar();
|
||||
|
|
@ -130,7 +130,7 @@ describe("Entity bottom bar", { tags: ["@tag.IDE"] }, () => {
|
|||
_.debuggerHelper.AssertClosed();
|
||||
//Verify if bottom bar opens on clicking debugger icon in query page.
|
||||
_.dataSources.CreateQueryAfterDSSaved();
|
||||
_.debuggerHelper.ClickDebuggerIcon();
|
||||
_.debuggerHelper.OpenDebugger();
|
||||
_.debuggerHelper.AssertOpen(PageType.Query);
|
||||
//Verify if bottom bar is closed on clicking close icon in query page.
|
||||
_.debuggerHelper.CloseBottomBar();
|
||||
|
|
|
|||
|
|
@ -33,13 +33,21 @@ describe("Sanitise toast error messages", () => {
|
|||
EditorNavigation.SelectEntityByName("Button1", EntityType.Widget);
|
||||
_.propPane.EnterJSContext("onClick", "{{a.kjbfjdfbkds()}}");
|
||||
_.agHelper.ClickButton("Submit");
|
||||
_.agHelper.WaitUntilToastDisappear("a is not defined");
|
||||
_.debuggerHelper.AssertDebugError("'a' is not defined.", "", true, false);
|
||||
});
|
||||
|
||||
it("2. Does not show type error label when js obj function does not exist", () => {
|
||||
EditorNavigation.SelectEntityByName("Button1", EntityType.Widget);
|
||||
_.propPane.EnterJSContext("onClick", "{{JSObject1.myFun1efef()}}");
|
||||
// Assert the lint error that shows up
|
||||
_.debuggerHelper.AssertDebugError(
|
||||
`"myFun1efef" doesn't exist in JSObject1`,
|
||||
"",
|
||||
false,
|
||||
false,
|
||||
);
|
||||
_.agHelper.ClickButton("Submit");
|
||||
// Assert the execution error that shows up
|
||||
_.agHelper.WaitUntilToastDisappear("Object1.myFun1efef is not a function");
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ describe("Inspect Entity", function () {
|
|||
it("1. Check whether depedencies and references are shown correctly", function () {
|
||||
cy.openPropertyPane("inputwidgetv2");
|
||||
cy.testJsontext("defaultvalue", "{{Button1.text}}");
|
||||
_.agHelper.GetNClick(".t--debugger-count");
|
||||
_.debuggerHelper.OpenDebugger();
|
||||
cy.contains(".ads-v2-tabs__list-tab", "Inspect entity").click();
|
||||
cy.contains(".t--dependencies-item", "Button1").click();
|
||||
cy.contains(".t--dependencies-item", "Input1");
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
import commonlocators from "../../../../locators/commonlocators.json";
|
||||
import { homePage } from "../../../../support/Objects/ObjectsCore";
|
||||
import { ObjectsRegistry } from "../../../../support/Objects/Registry";
|
||||
import EditorNavigation, {
|
||||
EntityType,
|
||||
|
|
@ -26,18 +24,18 @@ describe("Debugger logs", function () {
|
|||
logString = generateTestLogString();
|
||||
});
|
||||
|
||||
it("3. Console log on button click with normal moustache binding", function () {
|
||||
it("1. Console log on button click with normal moustache binding", function () {
|
||||
ee.DragDropWidgetNVerify("buttonwidget", 200, 200);
|
||||
// Testing with normal log in moustache binding
|
||||
propPane.EnterJSContext("onClick", `{{console.log("${logString}")}}`);
|
||||
agHelper.Sleep(2000);
|
||||
agHelper.ClickButton("Submit");
|
||||
debuggerHelper.ClickDebuggerIcon();
|
||||
debuggerHelper.OpenDebugger();
|
||||
agHelper.GetNClick(jsEditor._logsTab);
|
||||
debuggerHelper.DoesConsoleLogExist(logString);
|
||||
});
|
||||
|
||||
it("4. Console log on button click with arrow function IIFE", function () {
|
||||
it("2. Console log on button click with arrow function IIFE", function () {
|
||||
debuggerHelper.ClearLogs();
|
||||
EditorNavigation.SelectEntityByName("Button1", EntityType.Widget);
|
||||
// Testing with normal log in iifee
|
||||
|
|
@ -51,7 +49,7 @@ describe("Debugger logs", function () {
|
|||
debuggerHelper.DoesConsoleLogExist(logString);
|
||||
});
|
||||
|
||||
it("5. Console log on button click with function keyword IIFE", function () {
|
||||
it("3. Console log on button click with function keyword IIFE", function () {
|
||||
debuggerHelper.ClearLogs();
|
||||
EditorNavigation.SelectEntityByName("Button1", EntityType.Widget);
|
||||
// Testing with normal log in iifee
|
||||
|
|
@ -65,7 +63,7 @@ describe("Debugger logs", function () {
|
|||
debuggerHelper.DoesConsoleLogExist(logString);
|
||||
});
|
||||
|
||||
it("6. Console log on button click with async function IIFE", function () {
|
||||
it("4. Console log on button click with async function IIFE", function () {
|
||||
debuggerHelper.ClearLogs();
|
||||
// Testing with normal log in iifee
|
||||
EditorNavigation.SelectEntityByName("Button1", EntityType.Widget);
|
||||
|
|
@ -79,7 +77,7 @@ describe("Debugger logs", function () {
|
|||
debuggerHelper.DoesConsoleLogExist(logString);
|
||||
});
|
||||
|
||||
it("7. Console log on button click with mixed function IIFE", function () {
|
||||
it("5. Console log on button click with mixed function IIFE", function () {
|
||||
debuggerHelper.ClearLogs();
|
||||
// Testing with normal log in iifee
|
||||
EditorNavigation.SelectEntityByName("Button1", EntityType.Widget);
|
||||
|
|
@ -96,7 +94,7 @@ describe("Debugger logs", function () {
|
|||
debuggerHelper.DoesConsoleLogExist(logStringChild);
|
||||
});
|
||||
|
||||
it("8. Console log grouping on button click", function () {
|
||||
it("6. Console log grouping on button click", function () {
|
||||
debuggerHelper.ClearLogs();
|
||||
// Testing with normal log in iifee
|
||||
EditorNavigation.SelectEntityByName("Button1", EntityType.Widget);
|
||||
|
|
@ -116,7 +114,7 @@ describe("Debugger logs", function () {
|
|||
debuggerHelper.AssertConsecutiveConsoleLogCount(5);
|
||||
});
|
||||
|
||||
it("9. Console log grouping on button click with different log in between", function () {
|
||||
it("7. Console log grouping on button click with different log in between", function () {
|
||||
debuggerHelper.ClearLogs();
|
||||
// Testing with normal log in iifee
|
||||
EditorNavigation.SelectEntityByName("Button1", EntityType.Widget);
|
||||
|
|
@ -135,7 +133,7 @@ describe("Debugger logs", function () {
|
|||
debuggerHelper.AssertConsecutiveConsoleLogCount(2);
|
||||
});
|
||||
|
||||
it("10. Console log grouping on button click from different source", function () {
|
||||
it("8. Console log grouping on button click from different source", function () {
|
||||
debuggerHelper.ClearLogs();
|
||||
// Testing with normal log in iifee
|
||||
EditorNavigation.SelectEntityByName("Button1", EntityType.Widget);
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ describe("Debugger logs", { tags: ["@tag.IDE"] }, function () {
|
|||
_.agHelper.RefreshPage();
|
||||
// Wait for the debugger icon to be visible
|
||||
_.agHelper.AssertElementVisibility(".t--debugger-count");
|
||||
_.debuggerHelper.ClickDebuggerIcon();
|
||||
_.debuggerHelper.OpenDebugger();
|
||||
_.agHelper.GetNClick(_.jsEditor._logsTab);
|
||||
_.debuggerHelper.DoesConsoleLogExist(logString);
|
||||
});
|
||||
|
|
@ -286,7 +286,7 @@ describe("Debugger logs", { tags: ["@tag.IDE"] }, function () {
|
|||
|
||||
EditorNavigation.SelectEntityByName("Page1", EntityType.Page);
|
||||
_.agHelper.AssertElementVisibility(".t--debugger-count");
|
||||
_.debuggerHelper.ClickDebuggerIcon();
|
||||
_.debuggerHelper.OpenDebugger();
|
||||
|
||||
_.debuggerHelper.ClicklogEntityLink();
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ describe("Widget error state", function () {
|
|||
|
||||
//Check if the current value is shown in the debugger
|
||||
|
||||
_.debuggerHelper.ClickDebuggerIcon();
|
||||
_.debuggerHelper.OpenDebugger();
|
||||
cy.get("[data-testid=t--tab-ERROR]").click();
|
||||
//This feature is disabled in updated error log - epic 17720
|
||||
// _.debuggerHelper.LogStateContains("Test");
|
||||
|
|
@ -44,8 +44,8 @@ describe("Widget error state", function () {
|
|||
);
|
||||
|
||||
// All errors should be expanded by default
|
||||
//Updated count to 1 as the decision not to show triggerexecution/uncaughtpromise error in - epic 17720
|
||||
_.debuggerHelper.AssertVisibleErrorMessagesCount(1);
|
||||
//Updated count to 2 as the decision to show the widget trigger lint errors to show in the debugger
|
||||
_.debuggerHelper.AssertVisibleErrorMessagesCount(2);
|
||||
|
||||
// Recent errors are shown at the top of the list
|
||||
cy.testJsontext("label", "{{[]}}");
|
||||
|
|
@ -63,7 +63,7 @@ describe("Widget error state", function () {
|
|||
cy.deleteWidget();
|
||||
_.debuggerHelper.AssertVisibleErrorMessagesCount(0);
|
||||
cy.get("body").type(`{${modifierKey}}z`);
|
||||
_.debuggerHelper.AssertVisibleErrorMessagesCount(2);
|
||||
_.debuggerHelper.AssertVisibleErrorMessagesCount(3);
|
||||
|
||||
//Bug-2760: Error log on a widget property not clearing out when the widget property is deleted
|
||||
_.entityExplorer.DragDropWidgetNVerify(WIDGET.TABLE, 150, 300);
|
||||
|
|
|
|||
|
|
@ -43,13 +43,7 @@ describe(
|
|||
.should("be.visible")
|
||||
.contains("'lintError' is not defined.");
|
||||
|
||||
cy.get(commonlocators.debugger)
|
||||
.should("be.visible")
|
||||
.click({ force: true });
|
||||
|
||||
cy.get(commonlocators.errorTab)
|
||||
.should("be.visible")
|
||||
.click({ force: true });
|
||||
_.debuggerHelper.OpenDebugger();
|
||||
|
||||
cy.get(commonlocators.debugErrorMsg).should("have.length", 3);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -43,13 +43,7 @@ describe(
|
|||
.should("be.visible")
|
||||
.contains("'DATA' is not defined.");
|
||||
|
||||
cy.get(commonlocators.debugger)
|
||||
.should("be.visible")
|
||||
.click({ force: true });
|
||||
|
||||
cy.get(commonlocators.errorTab)
|
||||
.should("be.visible")
|
||||
.click({ force: true });
|
||||
_.debuggerHelper.OpenDebugger();
|
||||
|
||||
cy.get(commonlocators.debugErrorMsg).should("have.length", 6);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -91,10 +91,11 @@ describe(
|
|||
1,
|
||||
);
|
||||
//Open debugger by clicking debugger icon in canvas.
|
||||
debuggerHelper.ClickDebuggerIcon();
|
||||
agHelper.GetNAssertContains(
|
||||
debuggerHelper.locators._debuggerList,
|
||||
debuggerHelper.AssertDebugError(
|
||||
"This data identifier is evaluating to a duplicate value. Please use an identifier that evaluates to a unique value.",
|
||||
"",
|
||||
true,
|
||||
false,
|
||||
);
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import {
|
|||
import EditorNavigation, {
|
||||
EntityType,
|
||||
} from "../../../../../support/Pages/EditorNavigation";
|
||||
import * as _ from "../../../../../support/Objects/ObjectsCore";
|
||||
|
||||
describe(
|
||||
"Nested List widget V2 ",
|
||||
|
|
@ -40,8 +41,11 @@ describe(
|
|||
"List3",
|
||||
]);
|
||||
agHelper.GetElement("body").type(`{${agHelper._modifierKey}}{v}`);
|
||||
agHelper.ValidateToastMessage(
|
||||
_.debuggerHelper.OpenDebugger();
|
||||
_.debuggerHelper.ClickLogsTab();
|
||||
_.debuggerHelper.DoesConsoleLogExist(
|
||||
"Cannot have more than 3 levels of nesting in the list widget",
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -6,9 +6,11 @@ const commonlocators = require("../../../../../locators/commonlocators.json");
|
|||
import {
|
||||
agHelper,
|
||||
assertHelper,
|
||||
debuggerHelper,
|
||||
entityExplorer,
|
||||
propPane,
|
||||
} from "../../../../../support/Objects/ObjectsCore";
|
||||
import * as _ from "../../../../../support/Objects/ObjectsCore";
|
||||
const widgetsPage = require("../../../../../locators/Widgets.json");
|
||||
|
||||
const widgetSelector = (name) => `[data-widgetname-cy="${name}"]`;
|
||||
|
|
@ -72,7 +74,12 @@ describe(
|
|||
.type(`{${modifierKey}}{v}`);
|
||||
|
||||
cy.wait(500);
|
||||
cy.validateToastMessage("Cannot have more than 3 levels of nesting");
|
||||
_.debuggerHelper.OpenDebugger();
|
||||
_.debuggerHelper.ClickLogsTab();
|
||||
_.debuggerHelper.DoesConsoleLogExist(
|
||||
"Cannot have more than 3 levels of nesting",
|
||||
true,
|
||||
);
|
||||
cy.get(`${widgetSelector("List2Copy1")}`).should("not.exist");
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -44,15 +44,7 @@ describe(
|
|||
.should("be.visible")
|
||||
.contains("'lintErrror' is not defined.");
|
||||
|
||||
cy.get(commonlocators.debugger)
|
||||
.should("be.visible")
|
||||
.click({ force: true });
|
||||
|
||||
cy.get(commonlocators.errorTab)
|
||||
.should("be.visible")
|
||||
.click({ force: true });
|
||||
|
||||
cy.get(commonlocators.debugErrorMsg).should("have.length", 3);
|
||||
_.debuggerHelper.AssertErrorCount(3);
|
||||
});
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -124,7 +124,17 @@ describe(
|
|||
Cypress.env("TESTPASSWORD2"),
|
||||
);
|
||||
agHelper.VisitNAssert(currentUrl);
|
||||
agHelper.ValidateToastMessage("Resource Not Found"); //for 404 screen
|
||||
cy.get(locators.errorPageTitle).should(($x) => {
|
||||
//for 404 screen
|
||||
expect($x).contain(Cypress.env("MESSAGES").PAGE_NOT_FOUND());
|
||||
});
|
||||
cy.get(locators.errorPageDescription).should(($x) => {
|
||||
//for 404 screen
|
||||
expect($x).contain(
|
||||
"Either this page doesn't exist, or you don't have access to this page",
|
||||
);
|
||||
});
|
||||
agHelper.ValidateToastMessage("Resource Not Found");
|
||||
homePage.LogOutviaAPI();
|
||||
// visit the app as anonymous user and validate redirection to login page
|
||||
agHelper.VisitNAssert(currentUrl);
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ describe("JS Function Execution", { tags: ["@tag.JS"] }, function () {
|
|||
//It should open only in case of execution error.
|
||||
debuggerHelper.AssertClosed();
|
||||
//Verify there is no error shown in the response tab.
|
||||
debuggerHelper.ClickDebuggerIcon();
|
||||
debuggerHelper.OpenDebugger();
|
||||
debuggerHelper.ClickResponseTab();
|
||||
jsEditor.AssertParseError(false);
|
||||
agHelper.ActionContextMenuWithInPane({
|
||||
|
|
@ -400,7 +400,6 @@ describe("JS Function Execution", { tags: ["@tag.JS"] }, function () {
|
|||
jsEditor.EnableDisableAsyncFuncSettings(
|
||||
functionSetting.name,
|
||||
functionSetting.onPageLoad,
|
||||
functionSetting.confirmBeforeExecute,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
|
@ -496,12 +495,12 @@ return "yes";`;
|
|||
// Switch to settings tab
|
||||
agHelper.GetNClick(jsEditor._settingsTab);
|
||||
// Enable all settings
|
||||
jsEditor.EnableDisableAsyncFuncSettings("asyncToSync", true, false);
|
||||
jsEditor.EnableDisableAsyncFuncSettings("asyncToSync", true);
|
||||
|
||||
// Modify js object
|
||||
jsEditor.EditJSObj(syncJSCode, false);
|
||||
agHelper.RefreshPage();
|
||||
jsEditor.VerifyAsyncFuncSettings("asyncToSync", true, false);
|
||||
jsEditor.VerifyAsyncFuncSettings("asyncToSync", true);
|
||||
agHelper.ActionContextMenuWithInPane({
|
||||
action: "Delete",
|
||||
entityType: entityItems.JSObject,
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import {
|
|||
agHelper,
|
||||
apiPage,
|
||||
assertHelper,
|
||||
debuggerHelper,
|
||||
entityExplorer,
|
||||
entityItems,
|
||||
propPane,
|
||||
|
|
@ -58,7 +59,12 @@ describe(
|
|||
`{{PageLoadApi2.data.data}}`,
|
||||
);
|
||||
agHelper.RefreshPage();
|
||||
agHelper.ValidateToastMessage(`The action "PageLoadApi2" has failed.`);
|
||||
debuggerHelper.AssertDebugError(
|
||||
'The action "PageLoadApi2" has failed.',
|
||||
"",
|
||||
true,
|
||||
false,
|
||||
);
|
||||
});
|
||||
|
||||
after(() => {
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ describe(
|
|||
EditorNavigation.SelectEntityByName("Page1", EntityType.Page);
|
||||
agHelper.RefreshPage();
|
||||
|
||||
debuggerHelper.ClickDebuggerIcon();
|
||||
debuggerHelper.OpenDebugger();
|
||||
debuggerHelper.ClickLogsTab();
|
||||
debuggerHelper.DebuggerLogsFilter("JSObject1.astros");
|
||||
debuggerHelper.DoesConsoleLogExist("JS Function executed successfully");
|
||||
|
|
|
|||
|
|
@ -4,7 +4,11 @@ import {
|
|||
} from "../../../support/Pages/EditorNavigation";
|
||||
|
||||
const datasourceEditor = require("../../../locators/DatasourcesEditor.json");
|
||||
import { agHelper, dataSources } from "../../../support/Objects/ObjectsCore";
|
||||
import {
|
||||
agHelper,
|
||||
dataSources,
|
||||
debuggerHelper,
|
||||
} from "../../../support/Objects/ObjectsCore";
|
||||
const commonlocators = require("../../../locators/commonlocators.json");
|
||||
|
||||
describe(
|
||||
|
|
@ -60,9 +64,15 @@ describe(
|
|||
force: true,
|
||||
});
|
||||
cy.wait(2000);
|
||||
cy.get(commonlocators.toastmsg).contains(
|
||||
"NoiseTestQuery failed to execute",
|
||||
|
||||
debuggerHelper.OpenDebugger();
|
||||
debuggerHelper.ClickLogsTab();
|
||||
debuggerHelper.DoesConsoleLogExist(
|
||||
"Execution failed with status PE-STC-5000",
|
||||
true,
|
||||
"NoiseTestQuery",
|
||||
);
|
||||
|
||||
cy.wait("@postExecute").then(({ response }) => {
|
||||
expect(response.body.data.statusCode).to.eq("200 OK");
|
||||
});
|
||||
|
|
|
|||
|
|
@ -334,6 +334,8 @@ export class CommonLocators {
|
|||
_menuItem = ".bp3-menu-item";
|
||||
_slashCommandHintText = ".slash-command-hint-text";
|
||||
_selectionItem = ".rc-select-selection-item";
|
||||
errorPageTitle = ".t--error-page-title";
|
||||
errorPageDescription = ".t--error-page-description";
|
||||
_selectClearButton_testId = "selectbutton.btn.cancel";
|
||||
_selectClearButton_dataTestId = `[data-testid="${this._selectClearButton_testId}"]`;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ export class DebuggerHelper {
|
|||
[PageType.JsEditor]: ".t--js-editor-bottom-pane-container",
|
||||
[PageType.DataSources]: ".t--datasource-bottom-pane-container",
|
||||
},
|
||||
_ideBottomViewContainer: ".t--ide-bottom-view",
|
||||
_debuggerList: ".debugger-list",
|
||||
_debuggerFilter: "input[data-testid=t--debugger-search]",
|
||||
_debuggerSelectedTab: ".ads-v2-tabs__list-tab",
|
||||
|
|
@ -49,17 +50,16 @@ export class DebuggerHelper {
|
|||
_downStreamLogMessage: ".t--debugger-log-downstream-message",
|
||||
};
|
||||
|
||||
ClickDebuggerIcon(
|
||||
index?: number,
|
||||
force?: boolean,
|
||||
waitTimeInterval?: number,
|
||||
) {
|
||||
this.agHelper.GetNClick(
|
||||
this.locators._debuggerIcon,
|
||||
index,
|
||||
force,
|
||||
waitTimeInterval,
|
||||
);
|
||||
OpenDebugger() {
|
||||
// Open opens if it is not open yet
|
||||
cy.get("body").then(($body) => {
|
||||
if ($body.find(this.locators._ideBottomViewContainer).length === 0) {
|
||||
this.agHelper.GetNClick(this.locators._debuggerIcon, 0, false);
|
||||
} else {
|
||||
this.agHelper.GetNClick(this.commonLocators._errorTab, 0, true, 0);
|
||||
}
|
||||
});
|
||||
this.AssertOpen();
|
||||
}
|
||||
|
||||
ClickDebuggerToggle(expand = true, index = 0) {
|
||||
|
|
@ -93,7 +93,7 @@ export class DebuggerHelper {
|
|||
this.agHelper.GetNClick(this.locators._closeButton);
|
||||
}
|
||||
|
||||
AssertOpen(pageType: PageType) {
|
||||
AssertOpen(pageType?: PageType) {
|
||||
switch (pageType) {
|
||||
case PageType.Canvas:
|
||||
this.agHelper.AssertElementExist(this.locators._tabsContainer);
|
||||
|
|
@ -106,6 +106,10 @@ export class DebuggerHelper {
|
|||
this.locators._bottomPaneContainer[pageType],
|
||||
);
|
||||
break;
|
||||
default:
|
||||
this.agHelper.AssertElementVisibility(
|
||||
this.locators._ideBottomViewContainer,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -118,12 +122,19 @@ export class DebuggerHelper {
|
|||
this.agHelper.AssertSelectedTab(this.locators._debuggerSelectedTab, "true");
|
||||
}
|
||||
|
||||
DoesConsoleLogExist(text: string, exists = true) {
|
||||
DoesConsoleLogExist(text: string, exists = true, entityName?: string) {
|
||||
this.agHelper.GetNAssertContains(
|
||||
this.locators._logMessage,
|
||||
text,
|
||||
exists ? "exist" : "not.exist",
|
||||
);
|
||||
if (entityName) {
|
||||
this.agHelper
|
||||
.GetElement(this.locators._logMessage)
|
||||
.contains(text)
|
||||
.closest(".error")
|
||||
.contains(this.locators._logEntityLink, entityName);
|
||||
}
|
||||
}
|
||||
|
||||
DebuggerLogsFilter(text: string) {
|
||||
|
|
@ -187,9 +198,10 @@ export class DebuggerHelper {
|
|||
message: string,
|
||||
shouldOpenDebugger = true,
|
||||
shouldToggleDebugger = true,
|
||||
errorLabelIndex = 0,
|
||||
) {
|
||||
if (shouldOpenDebugger) {
|
||||
this.ClickDebuggerIcon();
|
||||
this.OpenDebugger();
|
||||
}
|
||||
this.agHelper.GetNClick(this.commonLocators._errorTab, 0, true, 0);
|
||||
|
||||
|
|
@ -198,7 +210,7 @@ export class DebuggerHelper {
|
|||
}
|
||||
|
||||
this.agHelper
|
||||
.GetText(this.locators._debuggerLabel, "text", 0)
|
||||
.GetText(this.locators._debuggerLabel, "text", errorLabelIndex)
|
||||
.then(($text) => {
|
||||
expect($text).to.eq(label);
|
||||
});
|
||||
|
|
@ -222,7 +234,7 @@ export class DebuggerHelper {
|
|||
|
||||
AssertDownStreamLogError(message: string, shouldOpenDebugger = true) {
|
||||
if (shouldOpenDebugger) {
|
||||
this.ClickDebuggerIcon();
|
||||
this.OpenDebugger();
|
||||
}
|
||||
|
||||
this.agHelper.GetNClick(this.commonLocators._responseTab, 0, true, 0);
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import Resizer, {
|
|||
import { CodeEditorWithGutterStyles } from "pages/Editor/JSEditor/styledComponents";
|
||||
import { ViewDisplayMode, ViewHideBehaviour } from "IDE/Interfaces/View";
|
||||
import { Button } from "@appsmith/ads";
|
||||
import classNames from "classnames";
|
||||
|
||||
const VIEW_MIN_HEIGHT = 38;
|
||||
|
||||
|
|
@ -112,6 +113,7 @@ const ViewHide = (props: ViewHideProps) => {
|
|||
|
||||
const BottomView = (props: Props) => {
|
||||
const panelRef = useRef<HTMLDivElement>(null);
|
||||
const { className = "" } = props;
|
||||
|
||||
// Handle the height of the view when toggling the hidden state
|
||||
useEffect(() => {
|
||||
|
|
@ -126,7 +128,10 @@ const BottomView = (props: Props) => {
|
|||
|
||||
return (
|
||||
<Container
|
||||
className={`select-text ${props.className || ""}`}
|
||||
className={classNames("select-text", {
|
||||
[className]: true,
|
||||
"t--ide-bottom-view": !props.hidden,
|
||||
})}
|
||||
displayMode={props.displayMode || ViewDisplayMode.BLOCK}
|
||||
ref={panelRef}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import type { JSCollection } from "entities/JSCollection";
|
|||
import type { CreateJSCollectionRequest } from "ee/api/JSActionAPI";
|
||||
import type { EventLocation } from "ee/utils/analyticsUtilTypes";
|
||||
import type { ApiResponse } from "api/ApiResponses";
|
||||
import type { ErrorActionPayload } from "../sagas/ErrorSagas";
|
||||
|
||||
export interface FetchJSCollectionsPayload {
|
||||
applicationId: string;
|
||||
|
|
@ -62,10 +63,12 @@ export const copyJSCollectionSuccess = (payload: JSCollection) => {
|
|||
};
|
||||
};
|
||||
|
||||
export const copyJSCollectionError = (payload: {
|
||||
id: string;
|
||||
destinationPageId: string;
|
||||
}) => {
|
||||
export const copyJSCollectionError = (
|
||||
payload: {
|
||||
id: string;
|
||||
destinationPageId: string;
|
||||
} & ErrorActionPayload,
|
||||
) => {
|
||||
return {
|
||||
type: ReduxActionErrorTypes.COPY_JS_ACTION_ERROR,
|
||||
payload,
|
||||
|
|
@ -90,10 +93,12 @@ export const moveJSCollectionSuccess = (payload: JSCollection) => {
|
|||
};
|
||||
};
|
||||
|
||||
export const moveJSCollectionError = (payload: {
|
||||
id: string;
|
||||
originalPageId: string;
|
||||
}) => {
|
||||
export const moveJSCollectionError = (
|
||||
payload: {
|
||||
id: string;
|
||||
originalPageId: string;
|
||||
} & ErrorActionPayload,
|
||||
) => {
|
||||
return {
|
||||
type: ReduxActionErrorTypes.MOVE_JS_ACTION_ERROR,
|
||||
payload,
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import type { ModalInfo } from "reducers/uiReducers/modalActionReducer";
|
|||
import type { OtlpSpan } from "UITelemetry/generateTraces";
|
||||
import type { ApiResponse } from "api/ApiResponses";
|
||||
import type { JSCollection } from "entities/JSCollection";
|
||||
import type { ErrorActionPayload } from "sagas/ErrorSagas";
|
||||
|
||||
export const createActionRequest = (payload: Partial<Action>) => {
|
||||
return {
|
||||
|
|
@ -205,10 +206,12 @@ export const moveActionSuccess = (payload: Action) => {
|
|||
};
|
||||
};
|
||||
|
||||
export const moveActionError = (payload: {
|
||||
id: string;
|
||||
originalPageId: string;
|
||||
}) => {
|
||||
export const moveActionError = (
|
||||
payload: {
|
||||
id: string;
|
||||
originalPageId: string;
|
||||
} & ErrorActionPayload,
|
||||
) => {
|
||||
return {
|
||||
type: ReduxActionErrorTypes.MOVE_ACTION_ERROR,
|
||||
payload,
|
||||
|
|
@ -233,10 +236,12 @@ export const copyActionSuccess = (payload: Action) => {
|
|||
};
|
||||
};
|
||||
|
||||
export const copyActionError = (payload: {
|
||||
id: string;
|
||||
destinationPageId: string;
|
||||
}) => {
|
||||
export const copyActionError = (
|
||||
payload: {
|
||||
id: string;
|
||||
destinationPageId: string;
|
||||
} & ErrorActionPayload,
|
||||
) => {
|
||||
return {
|
||||
type: ReduxActionErrorTypes.COPY_ACTION_ERROR,
|
||||
payload,
|
||||
|
|
|
|||
|
|
@ -368,7 +368,6 @@ const UserAuthActionTypes = {
|
|||
SAAS_GET_OAUTH_ACCESS_TOKEN: "SAAS_GET_OAUTH_ACCESS_TOKEN",
|
||||
GET_OAUTH_ACCESS_TOKEN: "GET_OAUTH_ACCESS_TOKEN",
|
||||
GET_OAUTH_ACCESS_TOKEN_SUCCESS: "GET_OAUTH_ACCESS_TOKEN_SUCCESS",
|
||||
GET_OAUTH_ACCESS_TOKEN_ERROR: "GET_OAUTH_ACCESS_TOKEN_ERROR",
|
||||
};
|
||||
const UserAuthActionErrorTypes = {
|
||||
CREATE_USER_ERROR: "CREATE_USER_ERROR",
|
||||
|
|
@ -379,6 +378,7 @@ const UserAuthActionErrorTypes = {
|
|||
LOGOUT_USER_ERROR: "LOGOUT_USER_ERROR",
|
||||
VERIFY_INVITE_ERROR: "VERIFY_INVITE_ERROR",
|
||||
INVITED_USER_SIGNUP_ERROR: "INVITED_USER_SIGNUP_ERROR",
|
||||
GET_OAUTH_ACCESS_TOKEN_ERROR: "GET_OAUTH_ACCESS_TOKEN_ERROR",
|
||||
};
|
||||
|
||||
const UserProfileActionTypes = {
|
||||
|
|
@ -1334,6 +1334,20 @@ export const ReduxActionErrorTypes = {
|
|||
...WorkspaceActionErrorTypes,
|
||||
};
|
||||
|
||||
export const toastMessageErrorTypes = {
|
||||
...AdminSettingsActionErrorTypes,
|
||||
...ApplicationActionErrorTypes,
|
||||
...AppViewActionErrorTypes,
|
||||
...DatasourceEditorActionErrorTypes,
|
||||
...GitActionErrorTypes,
|
||||
...ImportExportActionErrorTypes,
|
||||
...PlatformActionErrorTypes,
|
||||
...TenantActionErrorTypes,
|
||||
...UserAuthActionErrorTypes,
|
||||
...UserProfileActionErrorTypes,
|
||||
...WorkspaceActionErrorTypes,
|
||||
};
|
||||
|
||||
export type ReduxActionErrorType =
|
||||
(typeof ReduxActionErrorTypes)[keyof typeof ReduxActionErrorTypes];
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import type { JSActionEntity } from "ee/entities/DataTree/types";
|
||||
import type { JSActionEntity, WidgetEntity } from "ee/entities/DataTree/types";
|
||||
import { ENTITY_TYPE } from "entities/DataTree/dataTreeFactory";
|
||||
import type { DataTreeEntity } from "entities/DataTree/dataTreeTypes";
|
||||
|
||||
|
|
@ -9,6 +9,9 @@ const entityUniqueIdGetterMap: Record<
|
|||
[ENTITY_TYPE.JSACTION]: (entity) => {
|
||||
return (entity as JSActionEntity).actionId;
|
||||
},
|
||||
[ENTITY_TYPE.WIDGET]: (entity) => {
|
||||
return (entity as WidgetEntity).widgetId;
|
||||
},
|
||||
};
|
||||
|
||||
export default function getEntityUniqueIdForLogs(entity: DataTreeEntity) {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,16 @@
|
|||
import { isJSAction } from "ee/workers/Evaluation/evaluationUtils";
|
||||
import { isJSAction, isWidget } from "ee/workers/Evaluation/evaluationUtils";
|
||||
import type { DataTreeEntity } from "entities/DataTree/dataTreeTypes";
|
||||
import type { DataTreeEntityConfig } from "ee/entities/DataTree/types";
|
||||
|
||||
export default function isLintErrorLoggingEnabledForEntity(
|
||||
entity: DataTreeEntity,
|
||||
propertyPath: string,
|
||||
config: DataTreeEntityConfig,
|
||||
) {
|
||||
return isJSAction(entity);
|
||||
if (isJSAction(entity)) {
|
||||
return true;
|
||||
}
|
||||
if (isWidget(entity)) {
|
||||
return !(propertyPath in config.reactivePaths);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -192,10 +192,15 @@ export function* copyJSCollectionSaga(
|
|||
}
|
||||
} catch (e) {
|
||||
const actionName = actionObject ? actionObject.name : "";
|
||||
toast.show(createMessage(ERROR_JS_ACTION_COPY_FAIL, actionName), {
|
||||
kind: "error",
|
||||
});
|
||||
yield put(copyJSCollectionError(action.payload));
|
||||
yield put(
|
||||
copyJSCollectionError({
|
||||
...action.payload,
|
||||
show: true,
|
||||
error: {
|
||||
message: createMessage(ERROR_JS_ACTION_COPY_FAIL, actionName),
|
||||
},
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -265,13 +270,14 @@ export function* moveJSCollectionSaga(
|
|||
// @ts-expect-error: response.data is of type unknown
|
||||
yield put(moveJSCollectionSuccess(response.data));
|
||||
} catch (e) {
|
||||
toast.show(createMessage(ERROR_JS_ACTION_MOVE_FAIL, actionObject.name), {
|
||||
kind: "error",
|
||||
});
|
||||
yield put(
|
||||
moveJSCollectionError({
|
||||
id: action.payload.id,
|
||||
originalPageId: actionObject.pageId,
|
||||
show: true,
|
||||
error: {
|
||||
message: createMessage(ERROR_JS_ACTION_MOVE_FAIL, actionObject.name),
|
||||
},
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
|
@ -375,15 +381,15 @@ export function* saveJSObjectName(
|
|||
payload: {
|
||||
actionId: action.payload.id,
|
||||
oldName: collection.config.name,
|
||||
show: true,
|
||||
error: {
|
||||
message: createMessage(
|
||||
ERROR_JS_COLLECTION_RENAME_FAIL,
|
||||
action.payload.name,
|
||||
),
|
||||
},
|
||||
},
|
||||
});
|
||||
toast.show(
|
||||
createMessage(ERROR_JS_COLLECTION_RENAME_FAIL, action.payload.name),
|
||||
{
|
||||
kind: "error",
|
||||
},
|
||||
);
|
||||
log.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -267,9 +267,7 @@ function LogItem(props: LogItemProps) {
|
|||
size="md"
|
||||
/>
|
||||
<span className={`debugger-time ${props.severity}`}>
|
||||
{props.severity === Severity.ERROR
|
||||
? moment(parseInt(props.timestamp)).format("HH:mm:ss")
|
||||
: props.timestamp}
|
||||
{moment(parseInt(props.timestamp)).format("HH:mm:ss")}
|
||||
</span>
|
||||
|
||||
<Button
|
||||
|
|
|
|||
|
|
@ -158,6 +158,7 @@ export function* pasteWidgetSagas() {
|
|||
payload: {
|
||||
action: ReduxActionTypes.PASTE_COPIED_WIDGET_INIT,
|
||||
error,
|
||||
logToDebugger: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -370,7 +370,7 @@ const datasourceReducer = createReducer(initialState, {
|
|||
loadingTokenForDatasourceId: null,
|
||||
};
|
||||
},
|
||||
[ReduxActionTypes.GET_OAUTH_ACCESS_TOKEN_ERROR]: (
|
||||
[ReduxActionErrorTypes.GET_OAUTH_ACCESS_TOKEN_ERROR]: (
|
||||
state: DatasourceDataState,
|
||||
) => {
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@ import {
|
|||
} from "redux-saga/effects";
|
||||
import * as Sentry from "@sentry/react";
|
||||
import type { updateActionDataPayloadType } from "actions/pluginActionActions";
|
||||
import { executePageLoadActions } from "actions/pluginActionActions";
|
||||
import {
|
||||
clearActionResponse,
|
||||
executePageLoadActions,
|
||||
executePluginActionError,
|
||||
executePluginActionRequest,
|
||||
executePluginActionSuccess,
|
||||
|
|
@ -72,8 +72,7 @@ import {
|
|||
} from "sagas/ErrorSagas";
|
||||
import AnalyticsUtil from "ee/utils/AnalyticsUtil";
|
||||
import type { Action } from "entities/Action";
|
||||
import { ActionExecutionContext } from "entities/Action";
|
||||
import { PluginType } from "entities/Action";
|
||||
import { ActionExecutionContext, PluginType } from "entities/Action";
|
||||
import LOG_TYPE from "entities/AppsmithConsole/logtype";
|
||||
import {
|
||||
ACTION_EXECUTION_CANCELLED,
|
||||
|
|
@ -1267,9 +1266,8 @@ function* executePageLoadActionsSaga(
|
|||
checkAndLogErrorsIfCyclicDependency(layoutOnLoadActionErrors);
|
||||
} catch (e) {
|
||||
log.error(e);
|
||||
|
||||
toast.show(createMessage(ERROR_FAIL_ON_PAGE_LOAD_ACTIONS), {
|
||||
kind: "error",
|
||||
AppsmithConsole.error({
|
||||
text: createMessage(ERROR_FAIL_ON_PAGE_LOAD_ACTIONS),
|
||||
});
|
||||
}
|
||||
endSpan(span);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { call, spawn } from "redux-saga/effects";
|
||||
import {
|
||||
logActionExecutionError,
|
||||
showToastOnExecutionError,
|
||||
TriggerFailureError,
|
||||
} from "sagas/ActionExecution/errorUtils";
|
||||
import { isEmpty } from "lodash";
|
||||
|
|
@ -35,6 +35,6 @@ export function* executePostMessage(
|
|||
}
|
||||
}
|
||||
} catch (error) {
|
||||
yield call(logActionExecutionError, (error as Error).message, true);
|
||||
yield call(showToastOnExecutionError, (error as Error).message);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,15 +5,14 @@ import {
|
|||
import type { ApiResponse } from "api/ApiResponses";
|
||||
import { isString } from "lodash";
|
||||
import type { Types } from "utils/TypeHelpers";
|
||||
import type { ActionTriggerKeys } from "ee/workers/Evaluation/fns/index";
|
||||
import { getActionTriggerFunctionNames } from "ee/workers/Evaluation/fns/index";
|
||||
import { getAppMode } from "ee/selectors/applicationSelectors";
|
||||
import type { ActionTriggerKeys } from "ee/workers/Evaluation/fns";
|
||||
import { getActionTriggerFunctionNames } from "ee/workers/Evaluation/fns";
|
||||
import AnalyticsUtil from "ee/utils/AnalyticsUtil";
|
||||
import { setDebuggerSelectedTab, showDebugger } from "actions/debuggerActions";
|
||||
import { DEBUGGER_TAB_KEYS } from "components/editorComponents/Debugger/helpers";
|
||||
import store from "store";
|
||||
import showToast from "sagas/ToastSagas";
|
||||
import { call } from "redux-saga/effects";
|
||||
import { call, put } from "redux-saga/effects";
|
||||
|
||||
/*
|
||||
* The base trigger error that also logs the errors in the debugger.
|
||||
|
|
@ -55,39 +54,11 @@ export class ActionValidationError extends TriggerFailureError {
|
|||
}
|
||||
}
|
||||
|
||||
export function* logActionExecutionError(
|
||||
export function* showToastOnExecutionError(
|
||||
errorMessage: string,
|
||||
isExecuteJSFunc = true,
|
||||
showCTA = true,
|
||||
) {
|
||||
//Commenting as per decision taken for the error hanlding epic to not show the trigger errors in the debugger.
|
||||
// if (triggerPropertyName) {
|
||||
// AppsmithConsole.addErrors([
|
||||
// {
|
||||
// payload: {
|
||||
// id: `${source?.id}-${triggerPropertyName}`,
|
||||
// logType: LOG_TYPE.TRIGGER_EVAL_ERROR,
|
||||
// text: createMessage(DEBUGGER_TRIGGER_ERROR, triggerPropertyName),
|
||||
// source: {
|
||||
// type: ENTITY_TYPE.WIDGET,
|
||||
// id: source?.id ?? "",
|
||||
// name: source?.name ?? "",
|
||||
// propertyPath: triggerPropertyName,
|
||||
// },
|
||||
// messages: [
|
||||
// {
|
||||
// type: errorType,
|
||||
// message: { name: "TriggerExecutionError", message: errorMessage },
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// },
|
||||
// ]);
|
||||
// }
|
||||
|
||||
function onDebugClick() {
|
||||
const appMode = getAppMode(store.getState());
|
||||
if (appMode === "PUBLISHED") return null;
|
||||
|
||||
AnalyticsUtil.logEvent("OPEN_DEBUGGER", {
|
||||
source: "TOAST",
|
||||
});
|
||||
|
|
@ -95,16 +66,24 @@ export function* logActionExecutionError(
|
|||
store.dispatch(setDebuggerSelectedTab(DEBUGGER_TAB_KEYS.ERROR_TAB));
|
||||
}
|
||||
|
||||
if (isExecuteJSFunc)
|
||||
// This is the toast that is rendered when any unhandled error occurs in JS object.
|
||||
yield call(showToast, errorMessage, {
|
||||
kind: "error",
|
||||
action: {
|
||||
const action = showCTA
|
||||
? {
|
||||
text: "debug",
|
||||
effect: () => onDebugClick(),
|
||||
className: "t--toast-debug-button",
|
||||
},
|
||||
});
|
||||
}
|
||||
: undefined;
|
||||
|
||||
// This is the toast that is rendered when any unhandled error occurs in JS object.
|
||||
yield call(showToast, errorMessage, {
|
||||
kind: "error",
|
||||
action,
|
||||
});
|
||||
}
|
||||
|
||||
export function* showDebuggerOnExecutionError() {
|
||||
yield put(showDebugger(true));
|
||||
yield put(setDebuggerSelectedTab(DEBUGGER_TAB_KEYS.ERROR_TAB));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -5,14 +5,14 @@ import {
|
|||
getUserLocation,
|
||||
} from "./geolocationSaga";
|
||||
import { setUserCurrentGeoLocation } from "actions/browserRequestActions";
|
||||
import { logActionExecutionError } from "./errorUtils";
|
||||
import { showToastOnExecutionError } from "./errorUtils";
|
||||
|
||||
const mockFn = jest.fn();
|
||||
|
||||
jest.mock("./errorUtils.ts", () => ({
|
||||
// TODO: Fix this the next time the file is edited
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
logActionExecutionError: (payload: any) => mockFn(payload),
|
||||
showToastOnExecutionError: (payload: any) => mockFn(payload),
|
||||
}));
|
||||
|
||||
describe("getCurrentLocationSaga", () => {
|
||||
|
|
@ -86,7 +86,7 @@ describe("getCurrentLocationSaga", () => {
|
|||
|
||||
expect(iter.next().value).toHaveProperty(
|
||||
"payload.fn",
|
||||
logActionExecutionError,
|
||||
showToastOnExecutionError,
|
||||
);
|
||||
expect(iter.next().done).toBe(true);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import type { EventType } from "constants/AppsmithActionConstants/ActionConstants";
|
||||
import type { TriggerMeta } from "ee/sagas/ActionExecution/ActionExecutionSagas";
|
||||
import { call, put, spawn, take } from "redux-saga/effects";
|
||||
import { logActionExecutionError } from "sagas/ActionExecution/errorUtils";
|
||||
import { showToastOnExecutionError } from "sagas/ActionExecution/errorUtils";
|
||||
import { setUserCurrentGeoLocation } from "actions/browserRequestActions";
|
||||
import type { Channel } from "redux-saga";
|
||||
import { channel } from "redux-saga";
|
||||
|
|
@ -107,7 +107,7 @@ function* errorCallbackHandler(triggerMeta: TriggerMeta, listenerId?: string) {
|
|||
{ error: sanitizeGeolocationError(error) },
|
||||
listenerId,
|
||||
);
|
||||
yield call(logActionExecutionError, error.message, true);
|
||||
yield call(showToastOnExecutionError, error.message);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -122,7 +122,7 @@ export function* getCurrentLocationSaga(action: TGetGeoLocationDescription) {
|
|||
yield put(setUserCurrentGeoLocation(currentLocation));
|
||||
return currentLocation;
|
||||
} catch (error) {
|
||||
yield call(logActionExecutionError, (error as Error).message, true);
|
||||
yield call(showToastOnExecutionError, (error as Error).message);
|
||||
if (error instanceof GeolocationPositionError) {
|
||||
const sanitizedError = sanitizeGeolocationError(error);
|
||||
throw new GeoLocationError(sanitizedError.message, [sanitizedError]);
|
||||
|
|
@ -141,9 +141,8 @@ export function* watchCurrentLocation(
|
|||
// When a watch is already active, we will not start a new watch.
|
||||
// at a given point in time, only one watch is active
|
||||
yield call(
|
||||
logActionExecutionError,
|
||||
showToastOnExecutionError,
|
||||
"A watchLocation is already active. Clear it before before starting a new one",
|
||||
true,
|
||||
);
|
||||
|
||||
return;
|
||||
|
|
@ -171,7 +170,7 @@ export function* watchCurrentLocation(
|
|||
|
||||
export function* stopWatchCurrentLocation() {
|
||||
if (watchId === undefined) {
|
||||
yield call(logActionExecutionError, "No location watch active", true);
|
||||
yield call(showToastOnExecutionError, "No location watch active");
|
||||
return;
|
||||
}
|
||||
navigator.geolocation.clearWatch(watchId);
|
||||
|
|
|
|||
|
|
@ -106,7 +106,6 @@ import {
|
|||
createNewQueryAction,
|
||||
} from "actions/apiPaneActions";
|
||||
import type { Plugin } from "api/PluginApi";
|
||||
import * as log from "loglevel";
|
||||
import { shouldBeDefined } from "utils/helpers";
|
||||
import {
|
||||
apiEditorIdURL,
|
||||
|
|
@ -704,13 +703,14 @@ function* moveActionSaga(
|
|||
// @ts-expect-error: response is of type unknown
|
||||
yield put(moveActionSuccess(response.data));
|
||||
} catch (e) {
|
||||
toast.show(createMessage(ERROR_ACTION_MOVE_FAIL, actionObject.name), {
|
||||
kind: "error",
|
||||
});
|
||||
yield put(
|
||||
moveActionError({
|
||||
id: action.payload.id,
|
||||
originalPageId: action.payload.originalPageId,
|
||||
show: true,
|
||||
error: {
|
||||
message: createMessage(ERROR_ACTION_MOVE_FAIL, actionObject.name),
|
||||
},
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
|
@ -797,10 +797,13 @@ function* copyActionSaga(
|
|||
yield put(copyActionSuccess(payload));
|
||||
} catch (e) {
|
||||
const actionName = actionObject ? actionObject.name : "";
|
||||
toast.show(createMessage(ERROR_ACTION_COPY_FAIL, actionName), {
|
||||
kind: "error",
|
||||
});
|
||||
yield put(copyActionError(action.payload));
|
||||
yield put(
|
||||
copyActionError({
|
||||
...action.payload,
|
||||
show: true,
|
||||
error: { message: createMessage(ERROR_ACTION_COPY_FAIL, actionName) },
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -899,12 +902,9 @@ function* saveActionName(action: ReduxAction<{ id: string; name: string }>) {
|
|||
payload: {
|
||||
actionId: action.payload.id,
|
||||
oldName: api.config.name,
|
||||
message: createMessage(ERROR_ACTION_RENAME_FAIL, action.payload.name),
|
||||
},
|
||||
});
|
||||
toast.show(createMessage(ERROR_ACTION_RENAME_FAIL, action.payload.name), {
|
||||
kind: "error",
|
||||
});
|
||||
log.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
import get from "lodash/get";
|
||||
import omit from "lodash/omit";
|
||||
import { all, call, put, select, take, takeEvery } from "redux-saga/effects";
|
||||
import * as Sentry from "@sentry/react";
|
||||
import type {
|
||||
ReduxAction,
|
||||
ReduxActionWithMeta,
|
||||
|
|
@ -68,7 +67,6 @@ import { getCurrentBasePageId } from "selectors/editorSelectors";
|
|||
import { validateResponse } from "./ErrorSagas";
|
||||
import type { CreateDatasourceSuccessAction } from "actions/datasourceActions";
|
||||
import { removeTempDatasource } from "actions/datasourceActions";
|
||||
import { toast } from "@appsmith/ads";
|
||||
import type { AutoGeneratedHeader } from "pages/Editor/APIEditor/helpers";
|
||||
import { deriveAutoGeneratedHeaderState } from "pages/Editor/APIEditor/helpers";
|
||||
import { TEMP_DATASOURCE_ID } from "constants/Datasource";
|
||||
|
|
@ -744,6 +742,7 @@ function* handleApiNameChangeSaga(
|
|||
) {
|
||||
yield put(change(API_EDITOR_FORM_NAME, "name", action.payload.name));
|
||||
}
|
||||
|
||||
function* handleApiNameChangeSuccessSaga(
|
||||
action: ReduxAction<{ actionId: string }>,
|
||||
) {
|
||||
|
|
@ -751,19 +750,15 @@ function* handleApiNameChangeSuccessSaga(
|
|||
const actionObj: Action | undefined = yield select(getAction, actionId);
|
||||
yield take(ReduxActionTypes.FETCH_ACTIONS_FOR_PAGE_SUCCESS);
|
||||
if (!actionObj) {
|
||||
// Error case, log to sentry
|
||||
toast.show(createMessage(ERROR_ACTION_RENAME_FAIL, ""), {
|
||||
kind: "error",
|
||||
});
|
||||
|
||||
Sentry.captureException(
|
||||
new Error(createMessage(ERROR_ACTION_RENAME_FAIL, "")),
|
||||
{
|
||||
extra: {
|
||||
actionId: actionId,
|
||||
},
|
||||
yield put({
|
||||
type: ReduxActionErrorTypes.SAVE_ACTION_NAME_ERROR,
|
||||
payload: {
|
||||
actionId,
|
||||
show: true,
|
||||
error: { message: createMessage(ERROR_ACTION_RENAME_FAIL, "") },
|
||||
logToSentry: true,
|
||||
},
|
||||
);
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (actionObj.pluginType === PluginType.API) {
|
||||
|
|
|
|||
|
|
@ -199,6 +199,7 @@ export function* addWidgetAndMoveWidgetsSaga(
|
|||
payload: {
|
||||
action: ReduxActionTypes.WIDGETS_ADD_CHILD_AND_MOVE,
|
||||
error,
|
||||
logToDebugger: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
@ -424,6 +425,7 @@ function* moveWidgetsSaga(
|
|||
payload: {
|
||||
action: ReduxActionTypes.WIDGETS_MOVE,
|
||||
error,
|
||||
logToDebugger: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -471,12 +471,9 @@ export function* deleteDatasourceSaga(
|
|||
yield select(getDatasource, actionPayload.payload.id),
|
||||
`Datasource not found for id - ${actionPayload.payload.id}`,
|
||||
);
|
||||
toast.show((error as Error).message, {
|
||||
kind: "error",
|
||||
});
|
||||
yield put({
|
||||
type: ReduxActionErrorTypes.DELETE_DATASOURCE_ERROR,
|
||||
payload: { error, id: actionPayload.payload.id, show: false },
|
||||
payload: { error, id: actionPayload.payload.id, show: true },
|
||||
});
|
||||
AppsmithConsole.error({
|
||||
text: (error as Error).message,
|
||||
|
|
@ -736,12 +733,15 @@ function* getOAuthAccessTokenSaga(
|
|||
if (!appsmithToken) {
|
||||
// Error out because auth token should been here
|
||||
log.error(OAUTH_APPSMITH_TOKEN_NOT_FOUND);
|
||||
toast.show(OAUTH_AUTHORIZATION_APPSMITH_ERROR, {
|
||||
kind: "error",
|
||||
});
|
||||
yield put({
|
||||
type: ReduxActionTypes.GET_OAUTH_ACCESS_TOKEN_ERROR,
|
||||
payload: { datasourceId: datasourceId },
|
||||
type: ReduxActionErrorTypes.GET_OAUTH_ACCESS_TOKEN_ERROR,
|
||||
show: true,
|
||||
payload: {
|
||||
datasourceId: datasourceId,
|
||||
error: {
|
||||
message: OAUTH_AUTHORIZATION_APPSMITH_ERROR,
|
||||
},
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
|
@ -800,11 +800,14 @@ function* getOAuthAccessTokenSaga(
|
|||
}
|
||||
} catch (e) {
|
||||
yield put({
|
||||
type: ReduxActionTypes.GET_OAUTH_ACCESS_TOKEN_ERROR,
|
||||
payload: { datasourceId: datasourceId },
|
||||
});
|
||||
toast.show(OAUTH_AUTHORIZATION_FAILED, {
|
||||
kind: "error",
|
||||
type: ReduxActionErrorTypes.GET_OAUTH_ACCESS_TOKEN_ERROR,
|
||||
payload: {
|
||||
datasourceId: datasourceId,
|
||||
show: true,
|
||||
error: {
|
||||
message: OAUTH_AUTHORIZATION_FAILED,
|
||||
},
|
||||
},
|
||||
});
|
||||
log.error(e);
|
||||
}
|
||||
|
|
@ -913,25 +916,20 @@ function* testDatasourceSaga(actionPayload: ReduxAction<Datasource>) {
|
|||
}
|
||||
if (responseData.invalids && responseData.invalids.length) {
|
||||
AnalyticsUtil.logEvent("TEST_DATA_SOURCE_FAILED", {
|
||||
datasoureId: datasource?.id,
|
||||
datasourceId: datasource?.id,
|
||||
environmentId: currentEnvironment,
|
||||
environmentName: currentEnvDetails.name,
|
||||
pluginName: plugin?.name,
|
||||
errorMessages: responseData.invalids,
|
||||
messages: responseData.messages,
|
||||
});
|
||||
responseData.invalids.forEach((message: string) => {
|
||||
toast.show(message, {
|
||||
kind: "error",
|
||||
});
|
||||
});
|
||||
yield put({
|
||||
type: ReduxActionErrorTypes.TEST_DATASOURCE_ERROR,
|
||||
payload: {
|
||||
show: false,
|
||||
id: datasource.id,
|
||||
environmentId: currentEnvironment,
|
||||
messages: messages,
|
||||
show: true,
|
||||
error: { message: responseData.invalids.join(", ") },
|
||||
},
|
||||
});
|
||||
AppsmithConsole.error({
|
||||
|
|
@ -2107,10 +2105,12 @@ function* updateDatasourceAuthStateSaga(
|
|||
} catch (error) {
|
||||
yield put({
|
||||
type: ReduxActionErrorTypes.UPDATE_DATASOURCE_ERROR,
|
||||
payload: { error },
|
||||
});
|
||||
toast.show(OAUTH_AUTHORIZATION_FAILED, {
|
||||
kind: "error",
|
||||
payload: {
|
||||
error: {
|
||||
message: OAUTH_AUTHORIZATION_FAILED,
|
||||
},
|
||||
show: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import type {
|
||||
DeleteErrorLogPayload,
|
||||
LogDebuggerErrorAnalyticsPayload,
|
||||
import {
|
||||
type DeleteErrorLogPayload,
|
||||
type LogDebuggerErrorAnalyticsPayload,
|
||||
} from "actions/debuggerActions";
|
||||
import {
|
||||
addErrorLogs,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
import { get } from "lodash";
|
||||
import type { ReduxAction } from "ee/constants/ReduxActionConstants";
|
||||
import {
|
||||
type ReduxAction,
|
||||
toastMessageErrorTypes,
|
||||
} from "ee/constants/ReduxActionConstants";
|
||||
import {
|
||||
ReduxActionTypes,
|
||||
ReduxActionErrorTypes,
|
||||
|
|
@ -30,6 +33,14 @@ import { axiosConnectionAbortedCode } from "ee/api/ApiUtils";
|
|||
import { getLoginUrl } from "ee/utils/adminSettingsHelpers";
|
||||
import type { PluginErrorDetails } from "api/ActionAPI";
|
||||
import showToast from "sagas/ToastSagas";
|
||||
import AppsmithConsole from "../utils/AppsmithConsole";
|
||||
import type { SourceEntity } from "../entities/AppsmithConsole";
|
||||
import { getAppMode } from "ee/selectors/applicationSelectors";
|
||||
import { APP_MODE } from "../entities/App";
|
||||
|
||||
const shouldShowToast = (action: string) => {
|
||||
return action in toastMessageErrorTypes;
|
||||
};
|
||||
|
||||
/**
|
||||
* making with error message with action name
|
||||
|
|
@ -190,8 +201,9 @@ const getErrorMessageFromActionType = (
|
|||
enum ErrorEffectTypes {
|
||||
SHOW_ALERT = "SHOW_ALERT",
|
||||
SAFE_CRASH = "SAFE_CRASH",
|
||||
LOG_ERROR = "LOG_ERROR",
|
||||
LOG_TO_CONSOLE = "LOG_TO_CONSOLE",
|
||||
LOG_TO_SENTRY = "LOG_TO_SENTRY",
|
||||
LOG_TO_DEBUGGER = "LOG_TO_DEBUGGER",
|
||||
}
|
||||
|
||||
export interface ErrorActionPayload {
|
||||
|
|
@ -199,16 +211,33 @@ export interface ErrorActionPayload {
|
|||
show?: boolean;
|
||||
crash?: boolean;
|
||||
logToSentry?: boolean;
|
||||
logToDebugger?: boolean;
|
||||
sourceEntity?: SourceEntity;
|
||||
}
|
||||
|
||||
export function* errorSaga(errorAction: ReduxAction<ErrorActionPayload>) {
|
||||
const effects = [ErrorEffectTypes.LOG_ERROR];
|
||||
const effects = [ErrorEffectTypes.LOG_TO_CONSOLE];
|
||||
const { payload, type } = errorAction;
|
||||
const { error, logToSentry, show = true } = payload || {};
|
||||
const message = getErrorMessageFromActionType(type, error);
|
||||
const {
|
||||
error,
|
||||
logToDebugger,
|
||||
logToSentry,
|
||||
show = true,
|
||||
sourceEntity,
|
||||
} = payload || {};
|
||||
const appMode: APP_MODE = yield select(getAppMode);
|
||||
|
||||
// "show" means show a toast. We check if the error has been asked to not been shown
|
||||
// By making the default behaviour "true" we are ensuring undefined actions still pass through this check
|
||||
if (show) {
|
||||
effects.push(ErrorEffectTypes.SHOW_ALERT);
|
||||
// We want to show toasts for certain actions only so we avoid issues or if it is outside edit mode
|
||||
if (shouldShowToast(type) || appMode !== APP_MODE.EDIT) {
|
||||
effects.push(ErrorEffectTypes.SHOW_ALERT);
|
||||
}
|
||||
}
|
||||
|
||||
if (logToDebugger) {
|
||||
effects.push(ErrorEffectTypes.LOG_TO_DEBUGGER);
|
||||
}
|
||||
|
||||
if (error && error.crash) {
|
||||
|
|
@ -220,19 +249,26 @@ export function* errorSaga(errorAction: ReduxAction<ErrorActionPayload>) {
|
|||
effects.push(ErrorEffectTypes.LOG_TO_SENTRY);
|
||||
}
|
||||
|
||||
const message = getErrorMessageFromActionType(type, error);
|
||||
|
||||
for (const effect of effects) {
|
||||
switch (effect) {
|
||||
case ErrorEffectTypes.LOG_ERROR: {
|
||||
case ErrorEffectTypes.LOG_TO_CONSOLE: {
|
||||
logErrorSaga(errorAction);
|
||||
break;
|
||||
}
|
||||
case ErrorEffectTypes.LOG_TO_DEBUGGER: {
|
||||
AppsmithConsole.error({
|
||||
text: message,
|
||||
source: sourceEntity,
|
||||
});
|
||||
break;
|
||||
}
|
||||
case ErrorEffectTypes.SHOW_ALERT: {
|
||||
// This is the toast that is rendered when any page load API fails.
|
||||
yield call(showToast, message, { kind: "error" });
|
||||
|
||||
// TODO: Fix this the next time the file is edited
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
if ((window as any).Cypress) {
|
||||
if ("Cypress" in window) {
|
||||
if (message === "" || message === null) {
|
||||
yield put(
|
||||
safeCrashApp({
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ import {
|
|||
} from "actions/evaluationActions";
|
||||
import ConfigTreeActions from "utils/configTree";
|
||||
import {
|
||||
dynamicTriggerErrorHandler,
|
||||
showExecutionErrors,
|
||||
handleJSFunctionExecutionErrorLog,
|
||||
logJSVarCreatedEvent,
|
||||
logSuccessfulBindings,
|
||||
|
|
@ -341,16 +341,15 @@ export function* evaluateAndExecuteDynamicTrigger(
|
|||
triggerMeta,
|
||||
},
|
||||
);
|
||||
// TODO: Fix this the next time the file is edited
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const { errors = [] } = response as any;
|
||||
const { errors = [] } = response;
|
||||
|
||||
const transformedErrors: EvaluationError[] = yield call(
|
||||
transformTriggerEvalErrors,
|
||||
errors,
|
||||
);
|
||||
|
||||
yield call(dynamicTriggerErrorHandler, transformedErrors);
|
||||
if (transformedErrors.length) {
|
||||
yield fork(showExecutionErrors, transformedErrors);
|
||||
}
|
||||
yield fork(logDynamicTriggerExecution, {
|
||||
dynamicTrigger,
|
||||
errors: transformedErrors,
|
||||
|
|
|
|||
|
|
@ -55,14 +55,15 @@ function* handleInstallationFailure(
|
|||
text: `Failed to install library script at ${url}`,
|
||||
});
|
||||
|
||||
toast.show(message || `Failed to install library script at ${url}`, {
|
||||
kind: "error",
|
||||
});
|
||||
const applicationid: ReturnType<typeof getCurrentApplicationId> =
|
||||
yield select(getCurrentApplicationId);
|
||||
yield put({
|
||||
type: ReduxActionErrorTypes.INSTALL_LIBRARY_FAILED,
|
||||
payload: { url, show: false },
|
||||
payload: {
|
||||
url,
|
||||
show: true,
|
||||
message: message || `Failed to install library script at ${url}`,
|
||||
},
|
||||
});
|
||||
AnalyticsUtil.logEvent("INSTALL_LIBRARY", {
|
||||
url,
|
||||
|
|
@ -247,7 +248,16 @@ function* uninstallLibrarySaga(action: ReduxAction<JSLibrary>) {
|
|||
if (!isValidResponse) {
|
||||
yield put({
|
||||
type: ReduxActionErrorTypes.UNINSTALL_LIBRARY_FAILED,
|
||||
payload: accessor,
|
||||
payload: {
|
||||
show: true,
|
||||
accessor,
|
||||
error: {
|
||||
message: createMessage(
|
||||
customJSLibraryMessages.UNINSTALL_FAILED,
|
||||
name,
|
||||
),
|
||||
},
|
||||
},
|
||||
});
|
||||
AnalyticsUtil.logEvent("UNINSTALL_LIBRARY", {
|
||||
url: action.payload.url,
|
||||
|
|
@ -270,12 +280,19 @@ function* uninstallLibrarySaga(action: ReduxAction<JSLibrary>) {
|
|||
accessor,
|
||||
);
|
||||
if (!success) {
|
||||
toast.show(
|
||||
createMessage(customJSLibraryMessages.UNINSTALL_FAILED, name),
|
||||
{
|
||||
kind: "error",
|
||||
yield put({
|
||||
type: ReduxActionErrorTypes.UNINSTALL_LIBRARY_FAILED,
|
||||
payload: {
|
||||
accessor,
|
||||
show: true,
|
||||
error: {
|
||||
message: createMessage(
|
||||
customJSLibraryMessages.UNINSTALL_FAILED,
|
||||
name,
|
||||
),
|
||||
},
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
|
|
@ -297,8 +314,18 @@ function* uninstallLibrarySaga(action: ReduxAction<JSLibrary>) {
|
|||
success: true,
|
||||
});
|
||||
} catch (e) {
|
||||
toast.show(createMessage(customJSLibraryMessages.UNINSTALL_FAILED, name), {
|
||||
kind: "error",
|
||||
yield put({
|
||||
type: ReduxActionErrorTypes.UNINSTALL_LIBRARY_FAILED,
|
||||
payload: {
|
||||
accessor,
|
||||
show: true,
|
||||
error: {
|
||||
message: createMessage(
|
||||
customJSLibraryMessages.UNINSTALL_FAILED,
|
||||
name,
|
||||
),
|
||||
},
|
||||
},
|
||||
});
|
||||
AnalyticsUtil.logEvent("UNINSTALL_LIBRARY", {
|
||||
url: action.payload.url,
|
||||
|
|
|
|||
|
|
@ -86,7 +86,6 @@ import { UserCancelledActionExecutionError } from "sagas/ActionExecution/errorUt
|
|||
import type { EventLocation } from "ee/utils/analyticsUtilTypes";
|
||||
import AnalyticsUtil from "ee/utils/AnalyticsUtil";
|
||||
import { checkAndLogErrorsIfCyclicDependency } from "./helper";
|
||||
import { toast } from "@appsmith/ads";
|
||||
import { DEBUGGER_TAB_KEYS } from "components/editorComponents/Debugger/helpers";
|
||||
import {
|
||||
getJSActionPathNameToDisplay,
|
||||
|
|
@ -371,11 +370,16 @@ function* handleJSObjectNameChangeSuccessSaga(
|
|||
);
|
||||
yield take(ReduxActionTypes.FETCH_JS_ACTIONS_FOR_PAGE_SUCCESS);
|
||||
if (!actionObj) {
|
||||
// Error case, log to sentry
|
||||
toast.show(createMessage(ERROR_JS_COLLECTION_RENAME_FAIL, ""), {
|
||||
kind: "error",
|
||||
yield put({
|
||||
type: ReduxActionErrorTypes.SAVE_JS_COLLECTION_NAME_ERROR,
|
||||
payload: {
|
||||
actionId,
|
||||
show: true,
|
||||
error: {
|
||||
message: createMessage(ERROR_JS_COLLECTION_RENAME_FAIL, ""),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@ export function* lintTreeSaga(payload: LintTreeSagaRequestData) {
|
|||
yield call(logLatestLintPropertyErrors, {
|
||||
errors,
|
||||
dataTree: unevalTree,
|
||||
configTree,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -311,6 +311,7 @@ export function* resizeModalSaga(resizeAction: ReduxAction<ModalWidgetResize>) {
|
|||
payload: {
|
||||
action: WidgetReduxActionTypes.WIDGET_RESIZE,
|
||||
error,
|
||||
logToDebugger: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -374,16 +374,15 @@ function* BindWidgetToDatasource(
|
|||
isMock: datasource.isMock,
|
||||
formType: otherFields?.formType,
|
||||
});
|
||||
// TODO: Fix this the next time the file is edited
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
} catch (e: any) {
|
||||
toast.show(e.message, {
|
||||
hideProgressBar: false,
|
||||
kind: "error",
|
||||
});
|
||||
|
||||
} catch (e: unknown) {
|
||||
yield put({
|
||||
type: ReduxActionTypes.BIND_WIDGET_TO_DATASOURCE_ERROR,
|
||||
payload: {
|
||||
show: true,
|
||||
error: {
|
||||
message: e instanceof Error ? e.message : "Failed to Bind to widget",
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import {
|
|||
ReduxActionTypes,
|
||||
} from "ee/constants/ReduxActionConstants";
|
||||
import { getCurrentApplication } from "ee/selectors/applicationSelectors";
|
||||
import { toast } from "@appsmith/ads";
|
||||
import { getFlexLayersForSelectedWidgets } from "layoutSystems/autolayout/utils/AutoLayoutUtils";
|
||||
import type { FlexLayer } from "layoutSystems/autolayout/utils/types";
|
||||
import type { FlattenedWidgetProps } from "reducers/entityReducers/canvasWidgetsReducer";
|
||||
|
|
@ -76,13 +75,13 @@ export function* partialExportSaga(action: ReduxAction<PartialExportParams>) {
|
|||
});
|
||||
}
|
||||
} catch (e) {
|
||||
toast.show(createMessage(ERROR_IN_EXPORTING_APP), {
|
||||
kind: "error",
|
||||
});
|
||||
yield put({
|
||||
type: ReduxActionErrorTypes.PARTIAL_EXPORT_ERROR,
|
||||
payload: {
|
||||
error: "Error exporting application",
|
||||
show: true,
|
||||
error: {
|
||||
message: createMessage(ERROR_IN_EXPORTING_APP),
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,12 +35,12 @@ import { isWidgetPropertyNamePath } from "utils/widgetEvalUtils";
|
|||
import type { ActionEntityConfig } from "ee/entities/DataTree/types";
|
||||
import type { SuccessfulBindings } from "utils/SuccessfulBindingsMap";
|
||||
import SuccessfulBindingMap from "utils/SuccessfulBindingsMap";
|
||||
import { logActionExecutionError } from "./ActionExecution/errorUtils";
|
||||
import { getCurrentWorkspaceId } from "ee/selectors/selectedWorkspaceSelectors";
|
||||
import { getInstanceId } from "ee/selectors/tenantSelectors";
|
||||
import type { EvalTreeResponseData } from "workers/Evaluation/types";
|
||||
import { endSpan, startRootSpan } from "UITelemetry/generateTraces";
|
||||
import { getCollectionNameToDisplay } from "ee/utils/actionExecutionUtils";
|
||||
import { showToastOnExecutionError } from "./ActionExecution/errorUtils";
|
||||
|
||||
let successfulBindingsMap: SuccessfulBindingMap | undefined;
|
||||
|
||||
|
|
@ -57,14 +57,24 @@ export function* logJSVarCreatedEvent(
|
|||
});
|
||||
}
|
||||
|
||||
// TODO: Fix this the next time the file is edited
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export function* dynamicTriggerErrorHandler(errors: any[]) {
|
||||
if (errors.length > 0) {
|
||||
for (const error of errors) {
|
||||
const errorMessage =
|
||||
error.errorMessage.message.message || error.errorMessage.message;
|
||||
yield call(logActionExecutionError, errorMessage, true);
|
||||
export function* showExecutionErrors(errors: EvaluationError[]) {
|
||||
const appMode: APP_MODE = yield select(getAppMode);
|
||||
for (const error of errors) {
|
||||
const errorMessage = get(
|
||||
error,
|
||||
"errorMessage.message.message",
|
||||
error.errorMessage.message,
|
||||
);
|
||||
yield call(
|
||||
showToastOnExecutionError,
|
||||
errorMessage,
|
||||
appMode === APP_MODE.EDIT,
|
||||
);
|
||||
// Add it to the logs tab when in edit mode
|
||||
if (appMode === APP_MODE.EDIT) {
|
||||
AppsmithConsole.error({
|
||||
text: errorMessage,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { Severity } from "entities/AppsmithConsole";
|
||||
import LOG_TYPE from "entities/AppsmithConsole/logtype";
|
||||
import type { DataTree } from "entities/DataTree/dataTreeTypes";
|
||||
import type { ConfigTree, DataTree } from "entities/DataTree/dataTreeTypes";
|
||||
import { isEmpty } from "lodash";
|
||||
import AppsmithConsole from "utils/AppsmithConsole";
|
||||
import { getEntityNameAndPropertyPath } from "ee/workers/Evaluation/evaluationUtils";
|
||||
|
|
@ -11,11 +11,13 @@ import type { ENTITY_TYPE } from "ee/entities/AppsmithConsole/utils";
|
|||
|
||||
// We currently only log lint errors in JSObjects
|
||||
export function* logLatestLintPropertyErrors({
|
||||
configTree,
|
||||
dataTree,
|
||||
errors,
|
||||
}: {
|
||||
errors: LintErrorsStore;
|
||||
configTree: ConfigTree;
|
||||
dataTree: DataTree;
|
||||
errors: LintErrorsStore;
|
||||
}) {
|
||||
const errorsToAdd = [];
|
||||
const errorsToRemove = [];
|
||||
|
|
@ -23,8 +25,10 @@ export function* logLatestLintPropertyErrors({
|
|||
for (const path of Object.keys(errors)) {
|
||||
const { entityName, propertyPath } = getEntityNameAndPropertyPath(path);
|
||||
const entity = dataTree[entityName];
|
||||
const config = configTree[entityName];
|
||||
// only log lint errors in JSObjects
|
||||
if (!isLintErrorLoggingEnabledForEntity(entity)) continue;
|
||||
if (!isLintErrorLoggingEnabledForEntity(entity, propertyPath, config))
|
||||
continue;
|
||||
// only log lint errors (not warnings)
|
||||
const lintErrorsInPath = errors[path].filter(
|
||||
(error) => error.severity === Severity.ERROR,
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import {
|
|||
takeEvery,
|
||||
fork,
|
||||
} from "redux-saga/effects";
|
||||
import * as Sentry from "@sentry/react";
|
||||
import type { ApplicationPayload } from "entities/Application";
|
||||
import type {
|
||||
ReduxAction,
|
||||
|
|
@ -70,7 +69,6 @@ import { fetchDynamicValuesSaga } from "./FormEvaluationSaga";
|
|||
import type { FormEvalOutput } from "reducers/evaluationReducers/formEvaluationReducer";
|
||||
import { validateResponse } from "./ErrorSagas";
|
||||
import { getIsGeneratePageInitiator } from "utils/GenerateCrudUtil";
|
||||
import { toast } from "@appsmith/ads";
|
||||
import type { CreateDatasourceSuccessAction } from "actions/datasourceActions";
|
||||
import { createDefaultActionPayloadWithPluginDefaults } from "./ActionSagas";
|
||||
import { DB_NOT_SUPPORTED } from "ee/utils/Environments";
|
||||
|
|
@ -494,18 +492,16 @@ function* handleNameChangeSuccessSaga(
|
|||
yield take(ReduxActionTypes.FETCH_ACTIONS_FOR_PAGE_SUCCESS);
|
||||
if (!actionObj) {
|
||||
// Error case, log to sentry
|
||||
toast.show(createMessage(ERROR_ACTION_RENAME_FAIL, ""), {
|
||||
kind: "error",
|
||||
});
|
||||
|
||||
Sentry.captureException(
|
||||
new Error(createMessage(ERROR_ACTION_RENAME_FAIL, "")),
|
||||
{
|
||||
extra: {
|
||||
actionId: actionId,
|
||||
yield put({
|
||||
type: ReduxActionErrorTypes.SAVE_ACTION_NAME_ERROR,
|
||||
payload: {
|
||||
show: true,
|
||||
error: {
|
||||
message: createMessage(ERROR_ACTION_RENAME_FAIL, ""),
|
||||
},
|
||||
logToSentry: true,
|
||||
},
|
||||
);
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (actionObj.pluginType === PluginType.DB) {
|
||||
|
|
|
|||
|
|
@ -434,6 +434,7 @@ export function* addChildSaga(
|
|||
payload: {
|
||||
action: WidgetReduxActionTypes.WIDGET_ADD_CHILD,
|
||||
error,
|
||||
logToDebugger: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
@ -533,6 +534,7 @@ function* addUIEntitySaga(addEntityAction: ReduxAction<WidgetAddChild>) {
|
|||
payload: {
|
||||
action: WidgetReduxActionTypes.WIDGET_ADD_CHILD,
|
||||
error,
|
||||
logToDebugger: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -340,6 +340,7 @@ export function* deleteSaga(deleteAction: ReduxAction<WidgetDelete>) {
|
|||
payload: {
|
||||
action: WidgetReduxActionTypes.WIDGET_DELETE,
|
||||
error,
|
||||
logToDebugger: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
@ -481,6 +482,7 @@ function* deleteAllSelectedWidgetsSaga(
|
|||
payload: {
|
||||
action: WidgetReduxActionTypes.WIDGET_DELETE,
|
||||
error,
|
||||
logToDebugger: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -281,6 +281,7 @@ export function* resizeSaga(resizeAction: ReduxAction<WidgetResize>) {
|
|||
payload: {
|
||||
action: WidgetReduxActionTypes.WIDGET_RESIZE,
|
||||
error,
|
||||
logToDebugger: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
@ -1644,6 +1645,7 @@ function* pasteWidgetSaga(action: ReduxAction<PasteWidgetReduxAction>) {
|
|||
payload: {
|
||||
action: ReduxActionTypes.PASTE_COPIED_WIDGET_INIT,
|
||||
error,
|
||||
logToDebugger: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import {
|
|||
import type { ReduxAction } from "ee/constants/ReduxActionConstants";
|
||||
import type { LogActionPayload, Log } from "entities/AppsmithConsole";
|
||||
import { Severity, LOG_CATEGORY } from "entities/AppsmithConsole";
|
||||
import moment from "moment";
|
||||
import store from "store";
|
||||
import { isEmpty } from "lodash";
|
||||
|
||||
|
|
@ -29,7 +28,7 @@ function log(ev: Log) {
|
|||
}
|
||||
|
||||
function getTimeStamp() {
|
||||
return moment().format("HH:mm:ss");
|
||||
return Date.now().toString();
|
||||
}
|
||||
|
||||
function addLogs(logs: Log[]) {
|
||||
|
|
@ -90,7 +89,7 @@ function addErrors(errors: ErrorObject[]) {
|
|||
const refinedErrors = errors.map((error) => ({
|
||||
...error.payload,
|
||||
severity: error.severity ?? Severity.ERROR,
|
||||
timestamp: Date.now().toString(),
|
||||
timestamp: getTimeStamp(),
|
||||
occurrenceCount: 1,
|
||||
category: error.category ?? LOG_CATEGORY.PLATFORM_GENERATED,
|
||||
isExpanded: false,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user