### Apache Airflow version

2.7.0

### What happened

When a BigQuery job running in deferrable ends before completion - i.e. cancelled via the UI or terminated due a lack of resources - the precise error is not returned to the logs.  Instead a key error from within the `execute_complete` function is returned.

```
[2023-09-07, 09:17:52 UTC] {taskinstance.py:1824} ERROR - Task failed with exception
Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/airflow/providers/google/cloud/operators/bigquery.py", line 2874, in execute_complete
    raise AirflowException(event["message"])
KeyError: 'message'
```

https://github.com/apache/airflow/blob/main/airflow/providers/google/cloud/operators/bigquery.py#L2874-L2887 

### What you think should happen instead

When not running in deferrable mode, when the job is cancelled/fails during execution, the `_handle_job_error` is called resulting in the following output.

```
[2023-09-07, 09:16:35 UTC] {taskinstance.py:1824} ERROR - Task failed with exception
Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/airflow/providers/google/cloud/operators/bigquery.py", line 2848, in execute
    job.result(timeout=self.result_timeout, retry=self.result_retry)
  File "/usr/local/lib/python3.10/site-packages/google/cloud/bigquery/job/query.py", line 1499, in result
    do_get_result()
  File "/usr/local/lib/python3.10/site-packages/google/cloud/bigquery/job/query.py", line 1489, in do_get_result
    super(QueryJob, self).result(retry=retry, timeout=timeout)
  File "/usr/local/lib/python3.10/site-packages/google/cloud/bigquery/job/base.py", line 728, in result
    return super(_AsyncJob, self).result(timeout=timeout, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/google/api_core/future/polling.py", line 261, in result
    raise self._exception
google.api_core.exceptions.GoogleAPICallError: 200 Job execution was cancelled: User requested cancellation
```

It would appear that, even though `_handle_job_error` should get called when in deferrable mode, this doesn't happen if the job was running when it terminates.

https://github.com/apache/airflow/blob/main/airflow/providers/google/cloud/operators/bigquery.py#L2860-L2872

### How to reproduce

The code below will replicate the issue, however you need to provide a query that runs for enough time that enables you to cancel the job in UI.

Queries that have syntax errors never get started and are not affected by this.

```
from datetime import datetime

from airflow import models
from airflow.providers.google.cloud.operators.bigquery import BigQueryInsertJobOperator

with models.DAG(
    dag_id='bq_insert_job',
    start_date=datetime(2023, 8, 31),
    catchup=False,
    schedule='0 0 * * *',
) as dag:

    test1 = BigQueryInsertJobOperator(
        task_id=f'test1',
        sql='<INSERT LONG RUNNING QUERY>',
        deferrable=False,
    )

    test2 = BigQueryInsertJobOperator(
        task_id=f'test2',
        sql=f'<INSERT LONG RUNNING QUERY>',
        deferrable=True,
    )
```

### Operating System

n/a

### Versions of Apache Airflow Providers

apache-airflow-providers-google==10.6.0

### Deployment

Astronomer

### Deployment details

_No response_

### Anything else

_No response_

### Are you willing to submit PR?

- [X] Yes I am willing to submit a PR!

### Code of Conduct

- [X] I agree to follow this project's [Code of Conduct](https://github.com/apache/airflow/blob/main/CODE_OF_CONDUCT.md)

table name to create external table.
            If ``<project>`` is not included, project will be the
            project defined in the connection json.
        :param schema_fields: The schema field list as defined here:
            https://cloud.google.com/bigquery/docs/reference/rest/v2/tables#resource
        :param source_uris: The source Google Cloud
            Storage URI (e.g. gs://some-bucket/some-file.txt). A single wild
            per-object name can be used.
        :param source_format: File format to export.
        :param autodetect: Try to detect schema and format options automatically.
            Any option specified explicitly will be honored.
        :param compression: [Optional] The compression type of the data source.
            Possible values include GZIP and NONE.
            The default value is NONE.
            This setting is ignored for Google Cloud Bigtable,
            Google Cloud Datastore backups and Avro 
        :param ignore_unknown_values: [Optional] Indicates if BigQuery should allow
            extra values that are not represented in the table schema.
            If true, the extra values are ignored. If false, records with extra columns
            are treated as bad records, and if there are too many bad records, an
            invalid error is returned in the job result.
        :param max_bad_records: The maximum number of bad records that BigQuery can
            ignore when running the job.
        :param skip_leading_rows: Number of rows to skip when loading from a CSV.
        :param field_delimiter: The delimiter to use when loading from a CSV.
        :param quote_character: The value that is used to quote data sections in a CSV
            file.
        :param allow_quoted_newlines: Whether to allow quoted newlines (true) or not
            (false).
        :param allow_jagged_rows: Accept rows that are missing trailing optional columns.