fix: replace action execution cancellation toast errors with a better one (#16277)

* Remove error messages when user cancel action executions

* Add toast message after user cancels action execution

* Change error message

* Cypress validation for Bug #1609 added

Co-authored-by: Aishwarya UR <aishwarya@appsmith.com>
This commit is contained in:
Ayangade Adeoluwa 2022-08-31 19:08:42 +01:00 committed by GitHub
parent 55082812b2
commit 0e49c6efa9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 42 additions and 19 deletions

View File

@ -1,6 +1,6 @@
import { ObjectsRegistry } from "../../../../support/Objects/Registry";
let agHelper = ObjectsRegistry.AggregateHelper,
const agHelper = ObjectsRegistry.AggregateHelper,
locator = ObjectsRegistry.CommonLocators,
apiPage = ObjectsRegistry.ApiPage,
dataSources = ObjectsRegistry.DataSources;
@ -10,22 +10,23 @@ let dsName: any;
const largeResponseApiUrl = "https://api.publicapis.org/entries";
//"https://jsonplaceholder.typicode.com/photos";//Commenting since this is faster sometimes & case is failing
const ERROR_ACTION_EXECUTE_FAIL = (actionName: any) =>
`${actionName} action returned an error response`;
export const ACTION_EXECUTION_CANCELLED = (actionName: string) =>
`${actionName} was cancelled`;
describe("Abort Action Execution", function() {
it("1. Bug #14006 - Cancel Request button should abort API action execution", function() {
it("1. Bug #14006, #16093 - Cancel Request button should abort API action execution", function() {
apiPage.CreateAndFillApi(largeResponseApiUrl, "AbortApi", 0);
apiPage.RunAPI(false, 0);
agHelper.GetNClick(locator._cancelActionExecution, 0, true);
agHelper.AssertContains(ERROR_ACTION_EXECUTE_FAIL("AbortApi"));
agHelper.ActionContextMenuWithInPane("Delete", "Are you sure?")
agHelper.AssertContains(ACTION_EXECUTION_CANCELLED("AbortApi"));
agHelper.AssertElementAbsence(locator._specificToast("{}")); //Assert that empty toast does not appear - Bug #16093
agHelper.ActionContextMenuWithInPane("Delete", "Are you sure?");
});
// Queries were resolving quicker than we could cancel them
// Commenting this out till we can find a query that resolves slow enough for us to cancel its execution.
it("2. Bug #14006 Cancel Request button should abort Query action execution", function() {
it("2. Bug #14006, #16093 Cancel Request button should abort Query action execution", function() {
dataSources.CreateDataSource("MySql");
cy.get("@dsName").then(($dsName) => {
dsName = $dsName;
@ -37,8 +38,9 @@ describe("Abort Action Execution", function() {
dataSources.SetQueryTimeout(0);
dataSources.RunQuery(false, false, 0);
agHelper.GetNClick(locator._cancelActionExecution, 0, true);
agHelper.AssertContains(ERROR_ACTION_EXECUTE_FAIL("AbortQuery"));
agHelper.ActionContextMenuWithInPane("Delete", "Are you sure?")
agHelper.AssertContains(ACTION_EXECUTION_CANCELLED("AbortQuery"));
agHelper.AssertElementAbsence(locator._specificToast("{}")); //Assert that empty toast does not appear - Bug #16093
agHelper.ActionContextMenuWithInPane("Delete", "Are you sure?");
dataSources.DeleteDatasouceFromWinthinDS(dsName);
});
});

View File

@ -17,6 +17,7 @@ import { logoutUser } from "actions/userActions";
import { AUTH_LOGIN_URL } from "constants/routes";
import { getCurrentGitBranch } from "selectors/gitSyncSelectors";
import getQueryParamsObject from "utils/getQueryParamsObject";
import { UserCancelledActionExecutionError } from "sagas/ActionExecution/errorUtils";
const executeActionRegex = /actions\/execute/;
const timeoutErrorRegex = /timeout of (\d+)ms exceeded/;
@ -77,7 +78,7 @@ export const apiFailureResponseInterceptor = (error: any) => {
// Return if the call was cancelled via cancel token
if (axios.isCancel(error)) {
return;
throw new UserCancelledActionExecutionError();
}
// Return modified response if action execution failed

View File

@ -222,6 +222,8 @@ export const ERROR_DATEPICKER_MAX_DATE = () =>
export const ERROR_WIDGET_DOWNLOAD = (err: string) => `Download failed. ${err}`;
export const ERROR_PLUGIN_ACTION_EXECUTE = (actionName: string) =>
`${actionName} failed to execute`;
export const ACTION_EXECUTION_CANCELLED = (actionName: string) =>
`${actionName} was cancelled`;
export const ERROR_FAIL_ON_PAGE_LOAD_ACTIONS = () =>
`Failed to execute actions during page load`;
export const ERROR_ACTION_EXECUTE_FAIL = (actionName: string) =>

View File

@ -216,7 +216,7 @@ type Props = ReduxStateProps &
export const EMPTY_RESPONSE: ActionResponse = {
statusCode: "",
duration: "",
body: {},
body: "",
headers: {},
request: {
headers: {},

View File

@ -43,6 +43,7 @@ import {
ERROR_ACTION_EXECUTE_FAIL,
ERROR_FAIL_ON_PAGE_LOAD_ACTIONS,
ERROR_PLUGIN_ACTION_EXECUTE,
ACTION_EXECUTION_CANCELLED,
} from "@appsmith/constants/messages";
import { Variant } from "components/ads/common";
import {
@ -561,6 +562,19 @@ function* runActionSaga(
// When running from the pane, we just want to end the saga if the user has
// cancelled the call. No need to log any errors
if (e instanceof UserCancelledActionExecutionError) {
// cancel action but do not throw any error.
yield put({
type: ReduxActionErrorTypes.RUN_ACTION_ERROR,
payload: {
error: e.name,
id: reduxAction.payload.id,
show: false,
},
});
Toaster.show({
text: createMessage(ACTION_EXECUTION_CANCELLED, actionObject.name),
variant: Variant.danger,
});
return;
}
log.error(e);
@ -910,14 +924,14 @@ function* executePluginActionSaga(
params,
);
const response: ActionExecutionResponse = yield ActionAPI.executeAction(
formData,
timeout,
);
PerformanceTracker.stopAsyncTracking(
PerformanceTransactionName.EXECUTE_ACTION,
);
try {
const response: ActionExecutionResponse = yield ActionAPI.executeAction(
formData,
timeout,
);
PerformanceTracker.stopAsyncTracking(
PerformanceTransactionName.EXECUTE_ACTION,
);
yield validateResponse(response);
const payload = createActionExecutionResponse(response);
@ -949,7 +963,11 @@ function* executePluginActionSaga(
response: EMPTY_RESPONSE,
}),
);
throw new PluginActionExecutionError("Response not valid", false, response);
if (e instanceof UserCancelledActionExecutionError) {
throw new UserCancelledActionExecutionError();
}
throw new PluginActionExecutionError("Response not valid", false);
}
}