示例#1
0
def landoapi_exception(e):
    sentry.captureException()
    logger.exception('Uncaught communication exception with Lando API.')

    return render_template(
        'errorhandlers/default_error.html',
        title='Lando API returned an unexpected error',
        message=str(e)
    ), 500
示例#2
0
def landoapi_exception(e):
    sentry.captureException()
    logger.exception("Uncaught communication exception with Lando API.")

    return (
        render_template(
            "errorhandlers/default_error.html",
            title="Lando API returned an unexpected error",
            message=str(e),
        ),
        500,
    )
示例#3
0
def landoapi_communication(e):
    sentry.captureException()
    logger.exception('Uncaught communication exception with Lando API.')

    return render_template(
        'errorhandlers/default_error.html',
        title='Could not Communicate with Lando API',
        message=(
            'There was an error when trying to communicate with '
            'Lando API. Please try your request again later.'
        )
    ), 500
示例#4
0
def landoapi_communication(e):
    sentry.captureException()
    logger.exception("Uncaught communication exception with Lando API.")

    return (
        render_template(
            "errorhandlers/default_error.html",
            title="Could not Communicate with Lando API",
            message=("There was an error when trying to communicate with "
                     "Lando API. Please try your request again later."),
        ),
        500,
    )
示例#5
0
def unexpected_error(e):
    """Handler for all uncaught Exceptions."""
    logger.exception('unexpected error')
    sentry.captureException()

    return render_template(
        'errorhandlers/default_error.html',
        title='Oops! Something went wrong.',
        message=(
            'Something just went wrong. Try again or tell the team at '
            '#lando on irc.'
        )
    ), 500
示例#6
0
def unexpected_error(e):
    """Handler for all uncaught Exceptions."""

    logger.exception("unexpected error")
    sentry.captureException()

    return (
        render_template(
            "errorhandlers/default_error.html",
            title="Oops! Something went wrong.",
            message=(
                "Something just went wrong. Try again or tell the team at "
                "#lando on irc."),
        ),
        500,
    )
示例#7
0
def unexpected_error(e):
    """Handler for all uncaught Exceptions."""

    logger.exception("unexpected error")
    sentry.captureException()

    return (
        render_template(
            "errorhandlers/default_error.html",
            title="Oops! Something went wrong.",
            message=(
                "Something just went wrong. Try again or tell the team at "
                "#conduit on Matrix (https://matrix.to/#/#conduit:mozilla.org)."
            ),
        ),
        500,
    )
示例#8
0
def revision(revision_id, diff_id=''):
    # TODO:  Add diff ID when the API side is complete
    revision_api_url = '{host}/revisions/{revision_id}'.format(
        host=current_app.config['LANDO_API_URL'], revision_id=revision_id)

    try:
        result = requests.get(revision_api_url)
        result.raise_for_status()
    except requests.HTTPError as exc:
        if exc.response.status_code == 404:
            # The user looked up a non-existent revision, no special treatment
            # is necessary.
            abort(404)
        else:
            sentry.captureException()
            abort(500)
    except requests.ConnectionError:
        sentry.captureException()
        abort(500)

    revision = result.json()

    form = RevisionForm()
    if form.is_submitted():
        if form.validate():
            # TODO
            # Any more basic validation

            # Make request to API for landing
            diff_id = int(form.diff_id.data)
            land_response = requests.post(
                '{host}/landings'.format(
                    host=current_app.config['LANDO_API_URL']),
                json={
                    'revision_id': revision_id,
                    'diff_id': diff_id,
                },
                headers={
                    # TODO:  Add Phabricator API key for private revisions
                    # 'X-Phabricator-API-Key': '',
                    'Authorization':
                    'Bearer {}'.format(session['access_token']),
                    'Content-Type': 'application/json',
                })
            logger.info(land_response.json(), 'revision.landing.response')

            if land_response.status_code == 200:
                redirect_url = '/revisions/{revision_id}/{diff_id}'.format(
                    revision_id=revision_id, diff_id=diff_id)
                return redirect(redirect_url)
            else:
                # TODO:  Push an error on to an error stack to show in UI
                pass
        else:
            # TODO
            # Return validation errors
            pass

    # Set the diff id explicitly to avoid timing conflicts with
    # revision diff IDs being updated
    form.diff_id.data = revision['diff']['id']

    return render_template('revision/revision.html',
                           revision=revision,
                           author=revision['author'],
                           repo=revision['repo'],
                           parents=_flatten_parent_revisions(revision),
                           form=form)
    def post_landings_dryrun(self, revision_id, diff_id):
        """Queries Lando API's /landings/dryrun endpoint.

        The dryrun checks if there are any issues before landings.
        Issues can one be either a warning or a blocker.
        Users may acknowledge a warning and continue landing.
        If there are any blockers, landing is blocked until those resolve.

        Lando API also provides a confirmation token which is expected when
        performing the real landing via the POST /landings endpoint. This token
        tells the API that we've properly tried a dryrun first and acknowledged
        any warnings.

        The LandoAPIClient must be initialized with an auth0 access token to
        use this endpoint. If a user is not logged in, they should not be able
        to see warnings and blockers for landing.

        Args:
            revision_id: The id of the revision to land in 'D123' format.
            diff_id: The id of the specific diff of the revision to land.

        Returns:
            A dictionary with the following format:
            {
                'confirmation_token': token,
                'warnings': [{'id': id, 'message': message}, ...],
                'blockers': [{'id': id, 'message': message}, ...]
            }
            Does not return if unsuccessful.

        Exceptions:
            Raises an AssertionError if the LandoAPIClient was not initialized
            with an auth0_access_token.

            Raises a UIError in all cases where communication with lando-api
            and parsing the response fails.
        """
        # Callers should not be using this method if the user is not logged in.
        assert self.auth0_access_token

        # Setup request
        dryrun_url = '{host}/landings/dryrun'.format(host=self.landoapi_url)
        params = {
            'revision_id': revision_id,
            'diff_id': int(diff_id),
        }
        headers = {
            'Authorization': 'Bearer {}'.format(self.auth0_access_token),
            'Content-Type': 'application/json',
        }

        # Make request and handle response
        try:
            dryrun_response = requests.post(dryrun_url,
                                            json=params,
                                            headers=headers)
            dryrun_response.raise_for_status()
            return dryrun_response.json()
        except requests.HTTPError as e:
            # All HTTP errors from Lando API should be in the Connexions
            # problem exception format and include title, detail, and type.
            try:
                problem = e.response.json()
                uierror = UIError(title=problem['title'],
                                  message=problem['detail'],
                                  status_code=e.response.status_code)
            except (json.JSONDecodeError, KeyError) as e2:
                logger.error(
                    {
                        'url': dryrun_url,
                        'revision_id': revision_id,
                        'diff_id': diff_id,
                        'status_code': e.response.status_code,
                        'response_body': e.response.text,
                        'exception_type': str(type(e2)),
                        'exception_message': str(e2)
                    }, 'post_landings_dryrun.failed_reading_http_error')
                sentry.captureException()
                raise UIError(
                    title='Lando API did not respond successfully.',
                    message=('Unable to communicate with Lando API at this '
                             'time. Please try again later.'),
                    status_code=e.response.status_code)

            logger.debug(
                {
                    'url': dryrun_url,
                    'revision_id': revision_id,
                    'diff_id': diff_id,
                    'status_code': e.response.status_code,
                    'problem_title': problem['title'],
                    'problem_message': problem['detail'],
                    'problem_type': problem.get('type')
                }, 'post_landings_dryrun.failed_dryrun')
            raise uierror
        except requests.RequestException:
            logger.debug(
                {
                    'url': dryrun_url,
                    'revision_id': revision_id,
                    'diff_id': diff_id,
                }, 'post_landings_dryrun.failed_connection_to_landoapi')
            raise UIError(
                title='Failed to connect to Lando API.',
                message=('Unable to communicate with Lando API at this '
                         'time. Please try again later.'),
            )
示例#10
0
    def post_landings(self, revision_id, diff_id, confirmation_token):
        """Submit a land request to lando-api via the POST /landings endpoint.

        The LandoAPIClient must be initialized with an auth0 access token to
        use this method.

        Args:
            revision_id: The id of the revision to land in 'D123' format.
            diff_id: The id of the specific diff of the revision to land.

        Returns:
            If successful, returns True. Does not return if unsuccessful.

        Exceptions:
            Raises an AssertionError if the LandoAPIClient wasn't initialized
            with an auth0_access_token.

            Raises a LandingSubmissionError if the landing submission fails for
            any reason.
        """
        # Callers should not be using this method if the user is not logged in.
        assert self.auth0_access_token

        # Setup request
        post_landings_url = '{host}/landings'.format(host=self.landoapi_url)
        params = {
            'revision_id': revision_id,
            'diff_id': int(diff_id),
            'confirmation_token': confirmation_token,
        }
        headers = {
            'Authorization': 'Bearer {}'.format(self.auth0_access_token),
            'Content-Type': 'application/json',
        }

        # Make request and handle response
        try:
            land_response = requests.post(post_landings_url,
                                          json=params,
                                          headers=headers)
            land_response.raise_for_status()
            if land_response.status_code not in (200, 202):
                logger.error(
                    {
                        'url': post_landings_url,
                        'revision_id': revision_id,
                        'diff_id': diff_id,
                        'status_code': land_response.status_code,
                        'response_body': land_response.text
                    }, 'post_landings.invalid_2xx_code')
                sentry.captureMessage('landoapi returned an unexpected 2xx')

                raise LandingSubmissionError(
                    'Lando API did not respond successfully. '
                    'Please try again later.')
            return True
        except requests.HTTPError as e:
            # All HTTP errors from Lando API should be in the Connexions
            # problem exception format and include title, detail, and type.
            try:
                problem = e.response.json()
                problem_message = ('{title}: {detail}'.format(
                    title=problem['title'], detail=problem['detail']))
            except (json.JSONDecodeError, KeyError) as e2:
                logger.error(
                    {
                        'url': post_landings_url,
                        'revision_id': revision_id,
                        'diff_id': diff_id,
                        'status_code': e.response.status_code,
                        'response_body': e.response.text,
                        'exception_type': str(type(e2)),
                        'exception_message': str(e2)
                    }, 'post_landings.failed_reading_http_error')
                sentry.captureException()

                raise LandingSubmissionError(
                    'Lando API did not respond successfully. '
                    'Please try again later.')

            logger.debug(
                {
                    'url': post_landings_url,
                    'revision_id': revision_id,
                    'diff_id': diff_id,
                    'status_code': e.response.status_code,
                    'problem_message': problem_message,
                    'problem_type': problem.get('type')
                }, 'post_landings.failed_landing')
            raise LandingSubmissionError(error=problem_message,
                                         link=problem.get('type'))
        except requests.RequestException:
            logger.debug(
                {
                    'url': post_landings_url,
                    'revision_id': revision_id,
                    'diff_id': diff_id,
                }, 'post_landings.failed_connection_to_landoapi')
            raise LandingSubmissionError('Failed to connect to Lando API. '
                                         'Please try again later.')