Ejemplo n.º 1
0
    def run(self):
        failure_result = self._handle_basic_failure_modes()
        if failure_result:
            return failure_result

        result = process_xform_xml(self.domain, self.instance, self.attachments)
        submitted_form = result.submitted_form

        self._post_process_form(submitted_form)
        self._invalidate_caches(submitted_form.user_id)

        if submitted_form.is_submission_error_log:
            self.formdb.save_new_form(submitted_form)
            response = self.get_exception_response_and_log(submitted_form, self.path)
            return response, None, []

        cases = []
        with result.get_locked_forms() as xforms:
            instance = xforms[0]
            if instance.xmlns == DEVICE_LOG_XMLNS:
                try:
                    process_device_log(self.domain, instance)
                except Exception:
                    notify_exception(None, "Error processing device log", details={
                        'xml': self.instance,
                        'domain': self.domain
                    })
                    raise

            elif instance.is_duplicate:
                self.interface.save_processed_models([instance])
            elif not instance.is_error:
                try:
                    case_stock_result = self.process_xforms_for_cases(xforms)
                except (IllegalCaseId, UsesReferrals, MissingProductId,
                        PhoneDateValueError, InvalidCaseIndex) as e:
                    self._handle_known_error(e, instance, xforms)
                except Exception as e:
                    # handle / log the error and reraise so the phone knows to resubmit
                    # note that in the case of edit submissions this won't flag the previous
                    # submission as having been edited. this is intentional, since we should treat
                    # this use case as if the edit "failed"
                    handle_unexpected_error(self.interface, instance, e)
                    raise
                else:
                    instance.initial_processing_complete = True
                    self.save_processed_models(xforms, case_stock_result)
                    cases = case_stock_result.case_models

            errors = self.process_signals(instance)
            response = self._get_open_rosa_response(instance, errors)
            return response, instance, cases
Ejemplo n.º 2
0
    def process_device_log(self, device_log_form):
        self._conditionally_send_device_logs_to_sumologic(device_log_form)
        ignore_device_logs = settings.SERVER_ENVIRONMENT in settings.NO_DEVICE_LOG_ENVS
        if not ignore_device_logs:
            try:
                process_device_log(self.domain, device_log_form)
            except Exception as e:
                notify_exception(None, "Error processing device log", details={
                    'xml': self.instance,
                    'domain': self.domain
                })
                e.sentry_capture = False
                raise

        response = self._get_open_rosa_response(device_log_form)
        return FormProcessingResult(response, device_log_form, [], [], 'device-log')
Ejemplo n.º 3
0
    def process_device_log(self, device_log_form):
        self._conditionally_send_device_logs_to_sumologic(device_log_form)
        ignore_device_logs = settings.SERVER_ENVIRONMENT in settings.NO_DEVICE_LOG_ENVS
        if not ignore_device_logs:
            try:
                process_device_log(self.domain, device_log_form)
            except Exception as e:
                notify_exception(None, "Error processing device log", details={
                    'xml': self.instance,
                    'domain': self.domain
                })
                e.sentry_capture = False
                raise

        response = self._get_open_rosa_response(device_log_form)
        return FormProcessingResult(response, device_log_form, [], [], 'device-log')
Ejemplo n.º 4
0
    def run(self):
        failure_response = self._handle_basic_failure_modes()
        if failure_response:
            return FormProcessingResult(failure_response, None, [], [], 'known_failures')

        result = process_xform_xml(self.domain, self.instance, self.attachments)
        submitted_form = result.submitted_form

        self._post_process_form(submitted_form)
        self._invalidate_caches(submitted_form)
        submission_type = None

        if submitted_form.is_submission_error_log:
            self.formdb.save_new_form(submitted_form)
            response = self.get_exception_response_and_log(submitted_form, self.path)
            return FormProcessingResult(response, None, [], [], 'submission_error_log')

        cases = []
        ledgers = []
        submission_type = 'unknown'
        response_nature = error_message = None
        with result.get_locked_forms() as xforms:
            from casexml.apps.case.xform import get_and_check_xform_domain
            domain = get_and_check_xform_domain(xforms[0])
            if self.case_db:
                assert self.case_db.domain == domain
                case_db_cache = self.case_db
                case_db_cache.cached_xforms.extend(xforms)
            else:
                case_db_cache = self.interface.casedb_cache(domain=domain, lock=True, deleted_ok=True, xforms=xforms)

            with case_db_cache as case_db:
                instance = xforms[0]
                if instance.xmlns == DEVICE_LOG_XMLNS:
                    submission_type = 'device_log'
                    try:
                        process_device_log(self.domain, instance)
                    except Exception:
                        notify_exception(None, "Error processing device log", details={
                            'xml': self.instance,
                            'domain': self.domain
                        })
                        raise

                elif instance.is_duplicate:
                    submission_type = 'duplicate'
                    existing_form = xforms[1]
                    stub = UnfinishedSubmissionStub.objects.filter(
                        domain=instance.domain,
                        xform_id=existing_form.form_id
                    ).first()

                    result = None
                    if stub:
                        from corehq.form_processor.reprocess import reprocess_unfinished_stub_with_form
                        result = reprocess_unfinished_stub_with_form(stub, existing_form, lock=False)
                    elif existing_form.is_error:
                        from corehq.form_processor.reprocess import reprocess_form
                        result = reprocess_form(existing_form, lock_form=False)
                    if result and result.error:
                        submission_type = 'error'
                        error_message = result.error
                        if existing_form.is_error:
                            response_nature = ResponseNature.PROCESSING_FAILURE
                        else:
                            response_nature = ResponseNature.POST_PROCESSING_FAILIRE
                    else:
                        self.interface.save_processed_models([instance])
                elif not instance.is_error:
                    submission_type = 'normal'
                    try:
                        case_stock_result = self.process_xforms_for_cases(xforms, case_db)
                    except (IllegalCaseId, UsesReferrals, MissingProductId,
                            PhoneDateValueError, InvalidCaseIndex, CaseValueError) as e:
                        self._handle_known_error(e, instance, xforms)
                        submission_type = 'error'
                        response_nature = ResponseNature.PROCESSING_FAILURE
                    except Exception as e:
                        # handle / log the error and reraise so the phone knows to resubmit
                        # note that in the case of edit submissions this won't flag the previous
                        # submission as having been edited. this is intentional, since we should treat
                        # this use case as if the edit "failed"
                        handle_unexpected_error(self.interface, instance, e)
                        raise
                    else:
                        instance.initial_processing_complete = True
                        error_message = self.save_processed_models(case_db, xforms, case_stock_result)
                        if error_message:
                            response_nature = ResponseNature.POST_PROCESSING_FAILIRE
                        cases = case_stock_result.case_models
                        ledgers = case_stock_result.stock_result.models_to_save
                elif instance.is_error:
                    submission_type = 'error'

            response = self._get_open_rosa_response(instance, error_message, response_nature)
            return FormProcessingResult(response, instance, cases, ledgers, submission_type)