Skip to content

Commit

Permalink
Add error categories to task error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
mederly committed Feb 18, 2021
1 parent 889a0b0 commit 4f99f40
Show file tree
Hide file tree
Showing 7 changed files with 208 additions and 46 deletions.
Expand Up @@ -9,8 +9,11 @@
import com.evolveum.midpoint.util.LocalizableMessage;
import com.evolveum.midpoint.util.exception.*;
import com.evolveum.midpoint.xml.ns._public.common.common_3.CriticalityType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ErrorCategoryType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ErrorSelectorType;

import org.jetbrains.annotations.NotNull;

import java.io.PrintWriter;
import java.io.StringWriter;

Expand Down Expand Up @@ -46,25 +49,45 @@ public static CriticalityType getCriticality(ErrorSelectorType selector, Throwab
if (selector == null) {
return defaultValue;
}
if (exception instanceof CommunicationException) {
return defaultIfNull(selector.getNetwork(), defaultValue);
}
if (exception instanceof SecurityViolationException) {
return defaultIfNull(selector.getSecurity(), defaultValue);
}
if (exception instanceof PolicyViolationException) {
return defaultIfNull(selector.getPolicy(), defaultValue);
}
if (exception instanceof SchemaException) {
return defaultIfNull(selector.getSchema(), defaultValue);
ErrorCategoryType category = getErrorCategory(exception);
switch (category) {
case NETWORK:
return defaultIfNull(selector.getNetwork(), defaultValue);
case SECURITY:
return defaultIfNull(selector.getSecurity(), defaultValue);
case POLICY:
return defaultIfNull(selector.getPolicy(), defaultValue);
case SCHEMA:
return defaultIfNull(selector.getSchema(), defaultValue);
case CONFIGURATION:
return defaultIfNull(selector.getConfiguration(), defaultValue);
case UNSUPPORTED:
return defaultIfNull(selector.getUnsupported(), defaultValue);
case GENERIC:
return defaultIfNull(selector.getGeneric(), defaultValue);
default:
throw new AssertionError(category);
}
if (exception instanceof ConfigurationException || exception instanceof ExpressionEvaluationException) {
return defaultIfNull(selector.getConfiguration(), defaultValue);
}
if (exception instanceof UnsupportedOperationException) {
return defaultIfNull(selector.getUnsupported(), defaultValue);
}

// TODO improve the categorization code (e.g. not all expression evaluation exceptions are configuration-related)
@NotNull
public static ErrorCategoryType getErrorCategory(Throwable exception) {
if (exception instanceof CommunicationException) {
return ErrorCategoryType.NETWORK;
} else if (exception instanceof SecurityViolationException) {
return ErrorCategoryType.SECURITY;
} else if (exception instanceof PolicyViolationException) {
return ErrorCategoryType.POLICY;
} else if (exception instanceof SchemaException) {
return ErrorCategoryType.SCHEMA;
} else if (exception instanceof ConfigurationException || exception instanceof ExpressionEvaluationException) {
return ErrorCategoryType.CONFIGURATION;
} else if (exception instanceof UnsupportedOperationException) {
return ErrorCategoryType.UNSUPPORTED;
} else {
return ErrorCategoryType.GENERIC;
}
return defaultIfNull(selector.getGeneric(), defaultValue);
}

public static boolean isFatalCriticality(CriticalityType value, CriticalityType defaultValue) {
Expand Down
Expand Up @@ -745,10 +745,7 @@ public static boolean isRefreshOnRead(ResourceType resource) {

public static ErrorSelectorType getConnectorErrorCriticality(ResourceType resourceType) {
ResourceConsistencyType consistency = resourceType.getConsistency();
if (consistency == null) {
return null;
}
return consistency.getConnectorErrorCriticality();
return consistency != null ? consistency.getConnectorErrorCriticality() : null;
}

public static void checkNotInMaintenance(PrismObject<ResourceType> resource) throws MaintenanceException {
Expand Down
118 changes: 116 additions & 2 deletions infra/schema/src/main/resources/xml/ns/public/common/common-core-3.xsd
Expand Up @@ -7493,6 +7493,102 @@
<xsd:attribute name="id" type="xsd:long" use="optional"/>
</xsd:complexType>

<xsd:simpleType name="ErrorCategoryType">
<xsd:annotation>
<xsd:documentation>
Categorizes errors. Mirrors ErrorSelectorType structure.
</xsd:documentation>
<xsd:appinfo>
<a:since>4.3</a:since>
<a:experimental>true</a:experimental>
</xsd:appinfo>
</xsd:annotation>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="network">
<xsd:annotation>
<xsd:documentation>
Network errors (connection refused, timeouts, unreachable network, connection resets, ...).
</xsd:documentation>
<xsd:appinfo>
<jaxb:typesafeEnumMember name="NETWORK"/>
</xsd:appinfo>
</xsd:annotation>
</xsd:enumeration>
<xsd:enumeration value="security">
<xsd:annotation>
<xsd:documentation>
Security issues (failed authentication, permission denied, ...).
</xsd:documentation>
<xsd:appinfo>
<jaxb:typesafeEnumMember name="SECURITY"/>
</xsd:appinfo>
</xsd:annotation>
</xsd:enumeration>
<xsd:enumeration value="policy">
<xsd:annotation>
<xsd:documentation>
Policy violations. The operation failed because it violates
defined policies (e.g. exclusion policies), it fails data consistency checks,
etc.
</xsd:documentation>
<xsd:appinfo>
<jaxb:typesafeEnumMember name="POLICY"/>
</xsd:appinfo>
</xsd:annotation>
</xsd:enumeration>
<xsd:enumeration value="schema">
<xsd:annotation>
<xsd:documentation>
Schema and data format errors. These are errors that data
not complete, they contain unexpected elements, they do not match
pre-defined schema, etc.
</xsd:documentation>
<xsd:appinfo>
<jaxb:typesafeEnumMember name="SCHEMA"/>
</xsd:appinfo>
</xsd:annotation>
</xsd:enumeration>
<xsd:enumeration value="configuration">
<xsd:annotation>
<xsd:documentation>
Configuration errors. These are caused by misconfiguration of
midPoint, some of its components, the connector or the resource. This also
includes run-time errors that are likely caused by the configuration, such
as generic errors in the expressions.
</xsd:documentation>
<xsd:appinfo>
<jaxb:typesafeEnumMember name="CONFIGURATION"/>
</xsd:appinfo>
</xsd:annotation>
</xsd:enumeration>
<xsd:enumeration value="unsupported">
<xsd:annotation>
<xsd:documentation>
"Unsupported operation" issues. These errors are caused by
lack of functionality or support for the operation in connector
or any other part of midPoint. E.g. this may be missing (or disabled)
connector capability.
</xsd:documentation>
<xsd:appinfo>
<jaxb:typesafeEnumMember name="UNSUPPORTED"/>
</xsd:appinfo>
</xsd:annotation>
</xsd:enumeration>
<xsd:enumeration value="generic">
<xsd:annotation>
<xsd:documentation>
Generic, system and other non-specific issues. These errors
do not have any substantial definition about their cause. The error
may mean anything.
</xsd:documentation>
<xsd:appinfo>
<jaxb:typesafeEnumMember name="GENERIC"/>
</xsd:appinfo>
</xsd:annotation>
</xsd:enumeration>
</xsd:restriction>
</xsd:simpleType>

<xsd:simpleType name="CriticalityType">
<xsd:annotation>
<xsd:documentation>
Expand Down Expand Up @@ -29227,6 +29323,14 @@
</xsd:appinfo>
</xsd:annotation>
<xsd:sequence>
<xsd:element name="order" type="xsd:int" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Order in which this entry is to be evaluated. (Related to other entries.) Smaller numbers
go first. Entries with no order go last.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="situation" type="tns:TaskErrorSituationSelectorType" minOccurs="0">
<xsd:annotation>
<xsd:documentation>
Expand Down Expand Up @@ -29262,11 +29366,21 @@
<xsd:annotation>
<xsd:documentation>
Operation result status to match. Can be either PARTIAL_ERROR or FATAL_ERROR.
If not specified, any error matches.
If not present, we decide solely on error category. If error categories are not specified,
any error matches.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="errorCategory" type="tns:ErrorCategoryType" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>
Error category (network, security, policy, ...) to match. Note that some errors are not propagated
to the level where they can be recognized by this selector. So be careful and consider this feature
to be highly experimental.
If not present, we decide solely on the status.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<!-- Maybe better specification e.g. exception class can be added here? -->
</xsd:sequence>
</xsd:complexType>
<xsd:element name="taskErrorSituationSelector" type="tns:TaskErrorSituationSelectorType"/>
Expand Down
Expand Up @@ -1365,11 +1365,7 @@ private <T extends ObjectType, F extends ObjectType> PrismObject<T> executeAddit
result.addReturn("createdAccountOid", oid);
} else {
FocusConstraintsChecker.clearCacheFor(objectToAdd.asObjectable().getName());

oid = cacheRepositoryService.addObject(objectToAdd, addOpt, result);
if (oid == null) {
throw new SystemException("Repository addObject returned null OID while adding " + objectToAdd);
}
}
if (!change.isImmutable()) {
change.setOid(oid);
Expand Down
Expand Up @@ -1279,10 +1279,7 @@ private <F extends ObjectType> void finishLoadOfProjectionContext(LensContext<F>
if (resourceType == null) {
throw e;
} else {
ErrorSelectorType errorSelector = null;
if (resourceType.getConsistency() != null) {
errorSelector = resourceType.getConsistency().getConnectorErrorCriticality();
}
ErrorSelectorType errorSelector = ResourceTypeUtil.getConnectorErrorCriticality(resourceType);
if (errorSelector == null) {
if (e instanceof SchemaException) {
// Just continue evaluation. The error is recorded in the result.
Expand All @@ -1293,7 +1290,8 @@ private <F extends ObjectType> void finishLoadOfProjectionContext(LensContext<F>
throw e;
}
} else {
if (CriticalityType.FATAL.equals(ExceptionUtil.getCriticality(errorSelector, e, CriticalityType.FATAL))) {
CriticalityType criticality = ExceptionUtil.getCriticality(errorSelector, e, CriticalityType.FATAL);
if (criticality == CriticalityType.FATAL) {
throw e;
} else {
return;
Expand Down
Expand Up @@ -27,7 +27,8 @@
<errorHandlingStrategy>
<entry>
<situation>
<status>partial_error</status>
<!-- org.identityconnectors.framework.common.exceptions.ConnectorException: Booom! PowerFail script failed (generic) -->
<errorCategory>generic</errorCategory>
</situation>
<reaction>
<retryLater>
Expand All @@ -39,7 +40,10 @@
</entry>
<entry>
<situation>
<status>fatal_error</status>
<!-- com.evolveum.midpoint.util.exception.ExpressionEvaluationException: Fatally failing on 9-th user: e-000009
in expression in mapping in assigned mapping 'name ->' in role:582af892-2490-4fb1-bc83-368ade2c5eb4(errors-target)
in delta for user:null(e-000009) -->
<errorCategory>configuration</errorCategory>
</situation>
<reaction>
<retryLater>
Expand Down

0 comments on commit 4f99f40

Please sign in to comment.