Browse Source

Add exception handling for testing config

pull/1206/head
Hironsan 4 years ago
parent
commit
25b43f818f
5 changed files with 61 additions and 11 deletions
  1. 10
      app/api/exceptions.py
  2. 8
      app/api/serializers.py
  3. 13
      app/api/views.py
  4. 39
      frontend/components/containers/settings/ConfigCreationForm.vue
  5. 2
      frontend/components/containers/settings/LabelMapping.vue

10
app/api/exceptions.py

@ -1,5 +1,5 @@
from rest_framework import status
from rest_framework.exceptions import APIException, PermissionDenied
from rest_framework.exceptions import APIException, PermissionDenied, NotFound, ValidationError
class FileParseException(APIException):
@ -20,3 +20,11 @@ class AutoLabelingException(APIException):
class AutoLabeliingPermissionDenied(PermissionDenied):
default_detail = 'You do not have permission to perform auto labeling.' \
'Please ask the project administrators to add you.'
class URLConnectionError(NotFound):
default_detail = 'Failed to establish a connection. Please check the URL or network.'
class AWSTokenError(ValidationError):
default_detail = 'The security token included in the request is invalid.'

8
app/api/serializers.py

@ -268,5 +268,11 @@ class AutoLabelingConfigSerializer(serializers.ModelSerializer):
try:
RequestModelFactory.create(data['model_name'], data['model_attrs'])
except Exception:
raise serializers.ValidationError('The attributes does not match the model.')
model = RequestModelFactory.find(data['model_name'])
schema = model.schema()
required_fields = ', '.join(schema['required']) if 'required' in schema else ''
raise serializers.ValidationError(
'The attributes does not match the model.'
'You need to correctly specify the required fields: {}'.format(required_fields)
)
return data

13
app/api/views.py

@ -2,6 +2,8 @@ import collections
import json
import random
import botocore.exceptions
import requests
from auto_labeling_pipeline.menu import Options
from auto_labeling_pipeline.models import RequestModelFactory
from auto_labeling_pipeline.mappings import MappingTemplate
@ -25,7 +27,7 @@ from rest_framework.views import APIView
from rest_framework.parsers import MultiPartParser
from rest_framework_csv.renderers import CSVRenderer
from .exceptions import AutoLabelingException, AutoLabeliingPermissionDenied
from .exceptions import AutoLabelingException, AutoLabeliingPermissionDenied, URLConnectionError, AWSTokenError
from .filters import DocumentFilter
from .models import Project, Label, Document, RoleMapping, Role, Comment, AutoLabelingConfig
from .permissions import IsProjectAdmin, IsAnnotatorAndReadOnly, IsAnnotator, IsAnnotationApproverAndReadOnly, IsOwnAnnotation, IsAnnotationApprover, IsOwnComment
@ -541,11 +543,12 @@ class AutoLabelingConfigTest(APIView):
data={'valid': True, 'labels': output},
status=status.HTTP_200_OK
)
except requests.exceptions.ConnectionError:
raise URLConnectionError()
except botocore.exceptions.ClientError:
raise AWSTokenError()
except Exception as e:
return Response(
data={'valid': False},
status=status.HTTP_400_BAD_REQUEST
)
raise e
def pass_config_validation(self):
config = self.request.data['config']

39
frontend/components/containers/settings/ConfigCreationForm.vue

@ -86,7 +86,7 @@
<p class="font-weight-regular body-1">
Once you fetch the API response, you can convert the label into the defined one.
</p>
<label-mapping v-model="templateConfig.label_mapping" />
<label-mapping v-model="labelMapping" />
</v-stepper-content>
<v-stepper-content step="3">
@ -100,6 +100,18 @@
outlined
label="Sample Text"
/>
<v-alert
v-for="(error, index) in errors"
prominent
type="error"
:key="index"
>
<v-row align="center">
<v-col class="grow">
{{ error }}
</v-col>
</v-row>
</v-alert>
</v-stepper-content>
</v-card-text>
<v-card-actions class="me-4">
@ -163,13 +175,15 @@ export default Vue.extend({
data() {
return {
errors: [] as string[],
isLoading: false,
passTesting: false,
sampleText: '',
step: new StepCounter(1, 3),
templateName: null,
templateConfig: {},
templateNames: [] as string[]
templateNames: [] as string[],
labelMapping: []
}
},
@ -188,6 +202,12 @@ export default Vue.extend({
this.passTesting = false
},
deep: true
},
labelMapping: {
handler() {
this.passTesting = false
},
deep: true
}
},
@ -217,7 +237,7 @@ export default Vue.extend({
// @ts-ignore
template: this.templateConfig.template,
// @ts-ignore
labelMapping: this.templateConfig.label_mapping
labelMapping: this.labelMapping
}
return ConfigItem.parseFromUI(payload)
},
@ -229,6 +249,19 @@ export default Vue.extend({
.then(value => {
this.passTesting = value.valid
})
.catch((error) => {
const data = error.response.data
this.errors = []
if ('non_field_errors' in data) {
this.errors = data['non_field_errors']
} else if ('template' in data) {
this.errors.push('The template need to be filled.')
} else if ('detail' in data) {
this.errors.push(data['detail'])
} else {
this.errors = data
}
})
.finally(() => {
this.isLoading = false
})

2
frontend/components/containers/settings/LabelMapping.vue

@ -16,7 +16,7 @@
v-bind="attrs"
v-on="on"
>
Add a mapping
Add
</v-btn>
</template>
<v-card>

Loading…
Cancel
Save