diff --git a/frontend/common/stores/feature-list-store.ts b/frontend/common/stores/feature-list-store.ts
index b2067cf5695b..a47c9ffe27d5 100644
--- a/frontend/common/stores/feature-list-store.ts
+++ b/frontend/common/stores/feature-list-store.ts
@@ -90,8 +90,11 @@ const controller = {
}),
project_id: projectId,
})
- .then((res) =>
- Promise.all(
+ .then((res) => {
+ if (res.error) {
+ throw res.error?.error || res.error
+ }
+ return Promise.all(
(flag.multivariate_options || []).map((v) =>
data
.post(
@@ -107,8 +110,8 @@ const controller = {
data.get(
`${Project.api}projects/${projectId}/features/${res.data.id}/`,
),
- ),
- )
+ )
+ })
.then(() =>
Promise.all([
data.get(`${Project.api}projects/${projectId}/features/`),
@@ -322,123 +325,132 @@ const controller = {
store.saving()
API.trackEvent(Constants.events.EDIT_FEATURE)
- segmentOverridesProm.then(() => {
- if (mode !== 'VALUE') {
- prom = Promise.resolve()
- } else if (environmentFlag) {
- prom = data
- .get(
- `${Project.api}environments/${environmentId}/featurestates/${environmentFlag.id}/`,
- )
- .then((environmentFeatureStates) => {
- const multivariate_feature_state_values =
- environmentFeatureStates.multivariate_feature_state_values &&
- environmentFeatureStates.multivariate_feature_state_values.map(
- (v) => {
- const matching =
- environmentFlag.multivariate_feature_state_values.find(
- (m) => m.id === v.multivariate_feature_option,
- ) || {}
- return {
- ...v,
- percentage_allocation:
- matching.default_percentage_allocation,
- }
- },
- )
- environmentFlag.multivariate_feature_state_values =
- multivariate_feature_state_values
- return data.put(
+ segmentOverridesProm
+ .then(() => {
+ if (mode !== 'VALUE') {
+ prom = Promise.resolve()
+ } else if (environmentFlag) {
+ prom = data
+ .get(
`${Project.api}environments/${environmentId}/featurestates/${environmentFlag.id}/`,
- Object.assign({}, environmentFlag, {
- enabled: flag.default_enabled,
- feature_state_value: Utils.getTypedValue(
- flag.initial_value,
- undefined,
- true,
- ),
- }),
)
- })
- } else {
- prom = data.post(
- `${Project.api}environments/${environmentId}/featurestates/`,
- Object.assign({}, flag, {
- enabled: false,
- environment: environmentId,
- feature: projectFlag,
- }),
- )
- }
-
- const segmentOverridesRequest =
- mode === 'SEGMENT' && segmentOverrides
- ? (segmentOverrides.length
- ? updateSegmentPriorities(
- getStore(),
- segmentOverrides.map((override, index) => ({
- id: override.id,
- priority: index,
- })),
+ .then((environmentFeatureStates) => {
+ const multivariate_feature_state_values =
+ environmentFeatureStates.multivariate_feature_state_values &&
+ environmentFeatureStates.multivariate_feature_state_values.map(
+ (v) => {
+ const matching =
+ environmentFlag.multivariate_feature_state_values.find(
+ (m) => m.id === v.multivariate_feature_option,
+ ) || {}
+ return {
+ ...v,
+ percentage_allocation:
+ matching.default_percentage_allocation,
+ }
+ },
)
- : Promise.resolve([])
- ).then(() =>
- Promise.all(
- segmentOverrides.map((override) =>
- data.put(
- `${Project.api}features/featurestates/${override.feature_segment_value.id}/`,
- {
- ...override.feature_segment_value,
- enabled: override.enabled,
- feature_state_value: Utils.valueToFeatureState(
- override.value,
- ),
- multivariate_feature_state_values:
- override.multivariate_options &&
- override.multivariate_options.map((o) => {
- if (o.multivariate_feature_option) return o
- return {
- multivariate_feature_option:
- environmentFlag.multivariate_feature_state_values[
- o.multivariate_feature_option_index
- ].multivariate_feature_option,
- percentage_allocation: o.percentage_allocation,
- }
- }),
- },
+ environmentFlag.multivariate_feature_state_values =
+ multivariate_feature_state_values
+ return data.put(
+ `${Project.api}environments/${environmentId}/featurestates/${environmentFlag.id}/`,
+ Object.assign({}, environmentFlag, {
+ enabled: flag.default_enabled,
+ feature_state_value: Utils.getTypedValue(
+ flag.initial_value,
+ undefined,
+ true,
),
- ),
- ),
- )
- : Promise.resolve()
-
- Promise.all([prom, segmentOverridesRequest]).then(([res, segmentRes]) => {
- if (store.model) {
- store.model.keyedEnvironmentFeatures[projectFlag.id] = res
- if (segmentRes) {
- const feature = _.find(
- store.model.features,
- (f) => f.id === projectFlag.id,
- )
- if (feature) {
- feature.feature_segments = _.map(
- segmentRes.feature_segments,
- (segment) => ({
- ...segment,
- segment: segment.segment.id,
}),
)
- }
- }
+ })
+ } else {
+ prom = data.post(
+ `${Project.api}environments/${environmentId}/featurestates/`,
+ Object.assign({}, flag, {
+ enabled: false,
+ environment: environmentId,
+ feature: projectFlag,
+ }),
+ )
}
- if (store.model) {
- store.model.lastSaved = new Date().valueOf()
- }
- onComplete && onComplete()
- store.saved({})
+ const segmentOverridesRequest =
+ mode === 'SEGMENT' && segmentOverrides
+ ? (segmentOverrides.length
+ ? updateSegmentPriorities(
+ getStore(),
+ segmentOverrides.map((override, index) => ({
+ id: override.id,
+ priority: index,
+ })),
+ )
+ : Promise.resolve([])
+ ).then(() =>
+ Promise.all(
+ segmentOverrides.map((override) =>
+ data.put(
+ `${Project.api}features/featurestates/${override.feature_segment_value.id}/`,
+ {
+ ...override.feature_segment_value,
+ enabled: override.enabled,
+ feature_state_value: Utils.valueToFeatureState(
+ override.value,
+ ),
+ multivariate_feature_state_values:
+ override.multivariate_options &&
+ override.multivariate_options.map((o) => {
+ if (o.multivariate_feature_option) return o
+ return {
+ multivariate_feature_option:
+ environmentFlag
+ .multivariate_feature_state_values[
+ o.multivariate_feature_option_index
+ ].multivariate_feature_option,
+ percentage_allocation: o.percentage_allocation,
+ }
+ }),
+ },
+ ),
+ ),
+ ),
+ )
+ : Promise.resolve()
+
+ Promise.all([prom, segmentOverridesRequest])
+ .then(([res, segmentRes]) => {
+ if (store.model) {
+ store.model.keyedEnvironmentFeatures[projectFlag.id] = res
+ if (segmentRes) {
+ const feature = _.find(
+ store.model.features,
+ (f) => f.id === projectFlag.id,
+ )
+ if (feature) {
+ feature.feature_segments = _.map(
+ segmentRes.feature_segments,
+ (segment) => ({
+ ...segment,
+ segment: segment.segment.id,
+ }),
+ )
+ }
+ }
+ }
+
+ if (store.model) {
+ store.model.lastSaved = new Date().valueOf()
+ }
+ onComplete && onComplete()
+ store.saved({})
+ })
+ .catch((e) => {
+ API.ajaxHandler(store, e)
+ })
+ })
+ .catch((e) => {
+ API.ajaxHandler(store, e)
})
- })
},
editFeatureStateChangeRequest: async (
projectId: string,
@@ -770,13 +782,17 @@ const controller = {
)
}
- prom.then((res) => {
- if (store.model) {
- store.model.lastSaved = new Date().valueOf()
- }
- onComplete && onComplete()
- store.saved({})
- })
+ prom
+ .then((res) => {
+ if (store.model) {
+ store.model.lastSaved = new Date().valueOf()
+ }
+ onComplete && onComplete()
+ store.saved({})
+ })
+ .catch((e) => {
+ API.ajaxHandler(store, e)
+ })
},
getFeatureUsage(projectId, environmentId, flag, period) {
data
diff --git a/frontend/web/components/ErrorMessage.js b/frontend/web/components/ErrorMessage.js
index cbf1832f6c7e..b50f644e6093 100644
--- a/frontend/web/components/ErrorMessage.js
+++ b/frontend/web/components/ErrorMessage.js
@@ -28,7 +28,9 @@ export default class ErrorMessage extends PureComponent {