Problem/Motivation

responseToArray() fails with uninitialized properties: The responseToArray() method calls getter methods on the Partitech\PhpMistral\Clients\Response object without checking if
properties are initialized. For example, $response->getPages() throws an error when the $pages property is not set (which is the case for non-document chat responses).

Steps to reproduce

Running

$provider = \Drupal::service("ai.provider")->createInstance("mistral");                                                                                                             
$input = new ChatInput([new ChatMessage("user", "Hello")]);                                                                                                                         
$output = $provider->chat($input, "mistral-small-latest");        

results in

[error]  Error: Typed property Partitech\PhpMistral\Clients\Response::$pages must not be accessed before initialization in Partitech\PhpMistral\Clients\Response->getPages()    
     (line 528 of /app/vendor/partitech/php-mistral/src/Clients/Response.php) #0 /app/web/modules/contrib/ai_provider_mistral/src/Plugin/AiProvider/MistralProvider.php(469):         
     Partitech\PhpMistral\Clients\Response->getPages()                                                                                                                                
     #1 /app/web/modules/contrib/ai_provider_mistral/src/Plugin/AiProvider/MistralProvider.php(366): Drupal\ai_provider_mistral\Plugin\AiProvider\MistralProvider->responseToArray()  
     #2 [internal function]: Drupal\ai_provider_mistral\Plugin\AiProvider\MistralProvider->chat()                                                                                     
     #3 /app/web/modules/contrib/ai/src/Plugin/ProviderProxy.php(269): ReflectionMethod->invokeArgs()                                                                                 
     #4 /app/web/modules/contrib/ai/src/Plugin/ProviderProxy.php(133): Drupal\ai\Plugin\ProviderProxy->wrapperCall()                                                                  
     #5 /app/vendor/drush/drush/src/Commands/core/PhpCommands.php(33) : eval()'d code(9): Drupal\ai\Plugin\ProviderProxy->__call()                                                    
     #6 /app/vendor/drush/drush/src/Commands/core/PhpCommands.php(33): eval()                                                                                                         
     #7 [internal function]: Drush\Commands\core\PhpCommands->evaluate()                                                                                                              
     #8 /app/vendor/consolidation/annotated-command/src/CommandProcessor.php(276): call_user_func_array()   

Proposed resolution

Wrap $response->getPages() call in try-catch for \Error to handle uninitialized property.

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

petar_basic created an issue. See original summary.

petar_basic’s picture

Assigned: petar_basic » Unassigned
Status: Needs work » Needs review

Wrapped the potentially uninitialized property accessors (getModel(), getCreated(), getPages()) in try-catch blocks that catch \Error exceptions.
Properties that are initialized will be included in the output array; uninitialized properties are silently skipped.

fago’s picture

Status: Needs review » Needs work

Catching exceptions and silently throwing them away is a bad practice and usually creates other issues later on, when important-to see errors are not propagageted any more.

Besides that, I wonder why the above got snippet throws this exception? the code snippet seems right, so why is the property un-initialized? are we using the API somehow wrongly? To me, it looks like we are missing the underlying root-cause? Please elaborate.

petar_basic’s picture

Status: Needs work » Needs review

The Response class from php-mistral has properties without default values. The pages property is only set for OCR/document responses - it's never initialized for regular chats, therefore the above snippet causes the error when the responseToArray tries to call $response->getPages();

For the 'created' property - according to the mistral docs, the OCR response doesn't have it, so in that case it would be not initalized and throw an error.

So basically, the Response class handles multiple response formats from mistral API - but it doesn't seem to handle the optional fields properly.

We can fix this upstream - e.g. set default values
But because it is breaking the chats here now, I would still go with the current impl (and maybe remove once upstream is updated)

Also a possibility is to detect what kind of response we are handling and then access only relevant properties, but then it would need to be maintained in case anything changes upstream/in the mistral API.

What do you think?

  • fago committed 6672dca1 on 1.1.x authored by petar_basic
    fix: #3570604 Fix uninitialized pages property errors in responseToArray...
fago’s picture

Status: Needs review » Needs work

thanks. I agree, we should add a short-gap fix here. So I went with your MR and just made it a little more bullet-proof by rethrowing the exception if it's not having the excepted error + merged.

Still, the real fix to add the missing initialization is trivial and should be added upstream. Let's create a quick upstream PR please!
So setting to needs work for that.

petar_basic’s picture

Status: Needs work » Needs review

Created an upstream issue and PR to fix the root cause:

- Issue: https://github.com/partITech/php-mistral/issues/80
- PR: https://github.com/partITech/php-mistral/pull/81

The fix adds default values to the uninitialized properties.

fago’s picture

Status: Needs review » Needs work

wow, the maintain was quick! :-)
let's require https://github.com/partITech/php-mistral/releases/tag/v0.1.26 and remove our hack

petar_basic’s picture

Assigned: Unassigned » petar_basic
petar_basic’s picture

Assigned: petar_basic » Unassigned
Status: Needs work » Needs review

Bumped partitech/php-mistral from ^0.1.25 to ^0.1.26 and removed the workaround.

fago’s picture

Status: Needs review » Fixed

thx, merged.

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.