magento / magento2

Prior to making any Submission(s), you must sign an Adobe Contributor License Agreement, available here at: https://opensource.adobe.com/cla.html. All Submissions you make to Adobe Inc. and its affiliates, assigns and subsidiaries (collectively “Adobe”) are subject to the terms of the Adobe Contributor License Agreement.
http://www.magento.com
Open Software License 3.0
11.5k stars 9.31k forks source link

Error on checkout page when empty region field #7387

Closed ankitce closed 7 years ago

ankitce commented 7 years ago

Error message: Recoverable Error: Object of class Magento\Customer\Model\Data\Region could not be converted to string in /vendor/magento/framework/DB/Adapter/Pdo/Mysql.php

The checkout page halts after this error.

Originally reported issue - https://github.com/magento/magento2/issues/4187

Steps to reproduce: https://github.com/magento/magento2/issues/4187#issuecomment-255110528

birchestx commented 7 years ago

Affecting all UK checkouts, and any countries without preset regions. Needs urgent attention.

wsagen commented 7 years ago

We now have 3 clients directly affected by this and it's holding up their go live. Can we get a view on when this will be resolved?

veloraven commented 7 years ago

@ankitce please, format this issue according to the Issue reporting guidelines: with steps to reproduce, actual result and expected result. Please, also identify which version of Magento you are running. You can add links for original issues as additional information but please format this issue according to the template.

redboxmarcins commented 7 years ago

We are experiencing same issue on Magento EE 2.0.10 - but I believe this is not related to EE and same thing will happen with CE

wsagen commented 7 years ago

@veloraven - adding this on behalf of other users experiencing this issue. Users have reported this issue across versions of Magento and using native Magento functionality. Below I have included a module that you should install to reliably reproduce the issue. I realise this is artificial but it exposes the issue reliably. Test.zip Preconditions

  1. Magento 2.x CE or EE (seems to be an issue across versions)
  2. Install attached extension - (I've created a plugin that reliably produces the exception however users are reporting this exception within native Magento)

Steps to Reproduce

  1. Log in as customer which has a UK address
  2. Add item to the cart
  3. Proceed to checkout
  4. Select UK address and shipping method
  5. Click proceed

Expected Result Move to payment method page without error

Actual Result Exception reported when you select the UK address. Exception log file shows : "Recoverable Error: Object of class Magento\Customer\Model\Data\Region could not be converted to string in /vendor/magento/framework/DB/Adapter/Pdo/Mysql.php

Additional Information

I'm aware the save function has been deprecated and will be replaced with EntityManager functions. I don't believe this refactor has extended to the shipping address as yet. Even though deprecated, this function should still work.

This same save function is being used inside core code on Shipping Address in Magento\Quote\Observer\Frontend\Quote\Address\VatValidator::validate function around line 73. Using UK addresses with no region assigned, this would cause the same exception and could be the cause of the exception viewed by some users.

SerhiyShkolyarenko commented 7 years ago

@wsagen thank you for details! I performed these steps on clean Magento 2.0.10 and the whole checkout was OK. Order was placed successfully. Sorry, we support only native Magento code here(without any extensions). @ankitce @wsakaren @redboxmarcins could you point the steps to reproduce this issue? Is the issue 100% reproducible for you? Magento version also matters.

wsagen commented 7 years ago

@SerhiyShkolyarenko - I realise the checkout works without my test extension - because the core code statement causing the bug is not executed during this flow. There is a bug in your code when you save a UK address without a region ($address->save()). My extension simply reproduces this behaviour. I know the extension is artificial and we are not asking you to support the extension, I am asking you to use it as a tool to debug your core code that is causing an exception.

The same call is made during checkout when VAT ID validation is enabled in some instances - I have not seen steps here that will reliably reproduce it every time.

wsagen commented 7 years ago

Further to this, if extension code exposes issues with core code, this needs to be supported. At present this code is not extensible.

birchestx commented 7 years ago

@SerhiyShkolyarenko We have given you some code which reliably reproduces the issue. Its now down to you to fix it. Magento is a platform, its designed to be extended, you are writing code that can't be extended. Please just fix the issue, going back/forth like this is ridiculous.

SerhiyShkolyarenko commented 7 years ago

@wsagen you used direct model saving($address->save()) which is deprecated. Please look at \Magento\Framework\Model\AbstractModel::save(). For correct way of saving quote shipping assignment please refer to \Magento\Quote\Model\Quote\ShippingAssignment\ShippingAssignmentPersister::save(). Here I worked with latest develop branch.

webagil-kevin commented 7 years ago

I temporarily bypassed this bug:

In vendor/magento/framework/DB/Adapter/Pdo/Mysql.php

Search line 2920

            case 'varchar':
            case 'mediumtext':
            case 'text':
            case 'longtext':
                $value  = (string)$value;
                if ($column['NULLABLE'] && $value == '') {
                    $value = null;
                }
                break;

Replace by

            case 'varchar':
            case 'mediumtext':
            case 'text':
            case 'longtext':
                if ($column['COLUMN_NAME'] == 'region' AND !is_string($value)) {
                    $value = '';
                }
                $value  = (string)$value;
                if ($column['NULLABLE'] && $value == '') {
                    $value = null;
                }
                break;
SerhiyShkolyarenko commented 7 years ago

@DogSports do you have the steps to reproduce on the clean magento installation?

gloopro commented 7 years ago

We had this issues several months ago and implemented a work around. We created a module that extends the affected file and took advantage of magento 2's dependency injection to resolve it to the new class.

You can find the module here: https://github.com/gloong/module-quote

SerhiyShkolyarenko commented 7 years ago

@gloong how can I reproduce it on my instance? What are the steps for clean magento?

Flipmediaco commented 7 years ago

Importing Regions for the UK Resolves the issue, query as follows:-

INSERT INTO directory_country_region (country_id,code, default_name) values ("GB","AB","Aberdeenshire"), ("GB","AN","Anglesey"), ("GB","AG","Angus"), ("GB","AR","Argyll"), ("GB","AY","Ayrshire"), ("GB","BN","Banffshire"), ("GB","BD","Bedfordshire"), ("GB","BI","Berwickshire"), ("GB","BR","Breconshire"), ("GB","BK","Buckinghamshire"), ("GB","BU","Bute"), ("GB","CN","Caernarvonshire"), ("GB","CT","Caithness"), ("GB","CM","Cambridgeshire"), ("GB","CG","Cardiganshire"), ("GB","CR","Carmarthenshire"), ("GB","CH","Cheshire"), ("GB","CL","Clackmannanshire"), ("GB","CN","Cornwall and Isles of Scilly"), ("GB","CU","Cumbria"), ("GB","DI","Denbighshire"), ("GB","DB","Derbyshire"), ("GB","DV","Devon"), ("GB","DO","Dorset"), ("GB","DA","Dumbartonshire"), ("GB","DU","Dumfriesshire"), ("GB","DR","Durham"), ("GB","EL","East Lothian"), ("GB","ES","East Sussex"), ("GB","EX","Essex"), ("GB","FI","Fife"), ("GB","FL","Flintshire"), ("GB","GM","Glamorgan"), ("GB","GL","Gloucestershire"), ("GB","GR","Greater London"), ("GB","GM","Greater Manchester"), ("GB","HM","Hampshire"), ("GB","HT","Hertfordshire"), ("GB","IV","Inverness"), ("GB","KN","Kent"), ("GB","KE","Kincardineshire"), ("GB","KP","Kinross-shire"), ("GB","KC","Kirkcudbrightshire"), ("GB","LA","Lanarkshire"), ("GB","LC","Lancashire"), ("GB","LE","Leicestershire"), ("GB","LN","Lincolnshire"), ("GB","LD","London"), ("GB","ME","Merionethshire"), ("GB","MR","Merseyside"), ("GB","MO","Midlothian"), ("GB","MO","Monmouthshire"), ("GB","MG","Montgomeryshire"), ("GB","MY","Moray"), ("GB","NN","Nairnshire"), ("GB","NR","Norfolk"), ("GB","NH","Northamptonshire"), ("GB","NU","Northumberland"), ("GB","NY","North Yorkshire"), ("GB","NO","Nottinghamshire"), ("GB","OR","Orkney"), ("GB","OX","Oxfordshire"), ("GB","PB","Peebleshire"), ("GB","PM","Pembrokeshire"), ("GB","PT","Perthshire"), ("GB","RD","Radnorshire"), ("GB","RN","Renfrewshire"), ("GB","RS","Ross & Cromarty"), ("GB","RX","Roxburghshire"), ("GB","SL","Selkirkshire"), ("GB","SE","Shetland"), ("GB","SH","Shropshire"), ("GB","SO","Somerset"), ("GB","SY","South Yorkshire"), ("GB","ST","Staffordshire"), ("GB","SN","Stirlingshire"), ("GB","SU","Suffolk"), ("GB","SU","Surrey"), ("GB","SR","Sutherland"), ("GB","TW","Tyne and Wear"), ("GB","WR","Warwickshire"), ("GB","WE","West Lothian"), ("GB","WM","West Midlands"), ("GB","WS","West Sussex"), ("GB","WY","West Yorkshire"), ("GB","WG","Wigtownshire"), ("GB","WL","Wiltshire"), ("GB","WO","Worcestershire");

INSERT INTO directory_country_region_name (locale,region_id,name) SELECT "en_US", directory_country_region.region_id, directory_country_region.default_name FROM directory_country_region WHERE country_id = "GB";

Flipmediaco commented 7 years ago

Note to contributors; if you would like to recreate the issue, delete all records from directory_country_region and directory_country_region_name. This will then recreate the issue for any country, as all region data for all countries would be missing.

As a recoverable error shouldn't the query cater for the absence of the region data?

friimaind commented 6 years ago

Reopened https://github.com/magento/magento2/issues/12436

kunzi commented 3 years ago

We have this issue in Magento 2.3.6. I guess core fix is the way then.