Repository: saleor/saleor

Issue:
Setting external methods should throw errors when the method does not exist
### What I'm trying to achieve
I'm setting an external method that does not exist

### Steps to reproduce the problem
I base64 encoded `app:1234:some-id` that was never a real id external method id:

<img width="1440" alt="image" src="https://user-images.githubusercontent.com/2566928/154252619-496c1b91-ca79-4fe8-bc1d-abcd0cbb743c.png">

There is no error, but the delivery method is still null.


### What I expected to happen
I would expect an error response, rather than noop.

### Screenshots and logs
<!-- If applicable, add screenshots to help explain your problem. -->

**System information**
<!-- Provide the version of Saleor or whether you're using it from the `main` branch. If using Saleor Dashboard or Storefront, provide their versions too. -->
Saleor version:
- [ ] dev (current main)
- [ ] 3.0
- [ ] 2.11
- [ ] 2.10

Operating system:
- [ ] Windows
- [ ] Linux
- [ ] MacOS
- [ ] Other

Setting external methods should throw errors when the method does not exist
### What I'm trying to achieve
I'm setting an external method that does not exist

### Steps to reproduce the problem
I base64 encoded `app:1234:some-id` that was never a real id external method id:

<img width="1440" alt="image" src="https://user-images.githubusercontent.com/2566928/154252619-496c1b91-ca79-4fe8-bc1d-abcd0cbb743c.png">

There is no error, but the delivery method is still null.


### What I expected to happen
I would expect an error response, rather than noop.

### Screenshots and logs
<!-- If applicable, add screenshots to help explain your problem. -->

**System information**
<!-- Provide the version of Saleor or whether you're using it from the `main` branch. If using Saleor Dashboard or Storefront, provide their versions too. -->
Saleor version:
- [ ] dev (current main)
- [ ] 3.0
- [ ] 2.11
- [ ] 2.10

Operating system:
- [ ] Windows
- [ ] Linux
- [ ] MacOS
- [ ] Other



Discussion:

Resolving patch:
diff --git a/saleor/graphql/checkout/mutations/checkout_delivery_method_update.py b/saleor/graphql/checkout/mutations/checkout_delivery_method_update.py
--- a/saleor/graphql/checkout/mutations/checkout_delivery_method_update.py
+++ b/saleor/graphql/checkout/mutations/checkout_delivery_method_update.py
@@ -91,6 +91,16 @@ def perform_on_external_shipping_method(
             shipping_method_id=shipping_method_id,
         )
 
+        if delivery_method is None and shipping_method_id:
+            raise ValidationError(
+                {
+                    "delivery_method_id": ValidationError(
+                        f"Couldn't resolve to a node: ${shipping_method_id}",
+                        code=CheckoutErrorCode.NOT_FOUND,
+                    )
+                }
+            )
+
         cls._check_delivery_method(
             checkout_info, lines, shipping_method=delivery_method, collection_point=None
         )


Test patch:
diff --git a/saleor/graphql/checkout/tests/test_checkout.py b/saleor/graphql/checkout/tests/test_checkout.py
--- a/saleor/graphql/checkout/tests/test_checkout.py
+++ b/saleor/graphql/checkout/tests/test_checkout.py
@@ -4051,6 +4051,41 @@ def test_checkout_delivery_method_update_with_id_of_different_type_causes_and_er
     assert checkout.collection_point is None
 
 
+@patch(
+    "saleor.graphql.checkout.mutations.checkout_shipping_method_update."
+    "clean_delivery_method"
+)
+def test_checkout_delivery_method_with_nonexistant_id_results_not_found(
+    mock_clean_delivery,
+    api_client,
+    warehouse_for_cc,
+    checkout_with_item,
+    address,
+):
+    checkout = checkout_with_item
+    checkout.shipping_address = address
+    checkout.save(update_fields=["shipping_address"])
+    query = MUTATION_UPDATE_DELIVERY_METHOD
+    mock_clean_delivery.return_value = True
+
+    nonexistant_id = "YXBwOjEyMzQ6c29tZS1pZA=="
+    response = api_client.post_graphql(
+        query,
+        {
+            "token": checkout.token,
+            "deliveryMethodId": nonexistant_id,
+        },
+    )
+    data = get_graphql_content(response)["data"]["checkoutDeliveryMethodUpdate"]
+    checkout.refresh_from_db()
+
+    assert not data["checkout"]
+    assert data["errors"][0]["field"] == "deliveryMethodId"
+    assert data["errors"][0]["code"] == CheckoutErrorCode.NOT_FOUND.name
+    assert checkout.shipping_method is None
+    assert checkout.collection_point is None
+
+
 @patch(
     "saleor.graphql.checkout.mutations.checkout_shipping_method_update."
     "clean_delivery_method"