Item8908: Fatal error in WorkflowPlugin

pencil
Priority: Urgent
Current State: Closed
Released In:
Target Release: n/a
Applies To: Extension
Component: WorkflowPlugin
Branches:
Reported By: AndrewJones
Waiting For:
Last Change By: CrawfordCurrie
Using the latest version of the WorkflowPlugin, I get the following fatal error when I view the example topic (Sandbox.ControlledDocument):

Can't use string ("UNDERREVISION") as a HASH ref while "strict refs" in use at foswiki/lib/Foswiki/Plugins/WorkflowPlugin/Workflow.pm line 107.

I worked out that the problem occurs when hash is populated from line 57 in Workflow.pm. Something to do with the following lines:

my %data;
@data{@fields} = split(/\s*\|\s*/);
$this->{defaultState} ||= $data{state};
$this->{states}->{ $data{state} } = \%data;

I don't really understand whats going wrong with these lines, so I went back through the revisions in SVN and found where they changed from a simpler implementation. Once I reverted to the old code it worked fine again. A patch is attached.

I won't check in the patch, as someone might be able to fix the lines above to assign the hash correctly.

-- AndrewJones - 14 Apr 2010

Still wasn't working correctly, but I have uploaded a new patch which seems to do the trick.

-- AndrewJones - 21 Apr 2010

As I'm sure you realise, the patch is not a solution.

Some analysis. $this->{transitions} is an array of legal transitions, where each transition comes from a row in the transitions table. It is populated from the table using some rather obscure, though ultimately rather simple, perl. First, @fields is an array, each entry of which is the name of a column in the transition table. Next, for each data row in the transition table,
@data{@fields} = split(/\s*\|\s*/);
is a perl trick to assign the values in each column of the row to the hash element indexed by the corresponding column name. So, given:
| *State*       | *Action* | *Next State*  | *Allowed* |
| WAITINGFORQM  | reject   | UNDERREVISION | QualityManager,QualityGroup |
$this->transitions} contains an array, with one entry for each row of the transition table. So given the example above, you should expect to see:
$this->{transitions} =
[
 {
  'allowed' => 'QualityManager,QualityGroup',
  'next state' => 'UNDERREVISION',
  'action' => 'reject',
  'state' => 'WAITINGFORQM'
 }
]
Later in the code, at the point you identified as causing the crash,
    foreach ( @{ $this->{transitions} } ) {
        my $allowed = $topic->expandMacros( $_->{allowed} );
        my $nextState = $topic->expandMacros( $_->{nextstate} );
        if ( $_->{state} eq $currentState               ##### Line 107
            && _isAllowed($allowed) && $nextState )
        {
For this line to fail in the way you describe, $_ has to contain the string 'UNDERREVISION'. For that to happen, $this->{transitions} has to contain at least one entry containing just this string. For that to happen as a result of the reading of the transition table is impossible, as far as I can tell from reading the code. So, to reproduce this crash requires data - at the very least, the state table, the transition table, and a topic where the crash happens. Once we can reproduce it reliably, it can be fixed.

Needless to say I don't see the error in my test environment, when the plugin is installed in any of Foswiki 1.1, Foswiki 1.0.9, or TWiki 4.2.3.

-- CrawfordCurrie - 21 Apr 2010

Pretty sure I nailed this in the latest release.

-- CrawfordCurrie - 26 Aug 2010

 
Topic revision: r6 - 26 Aug 2010, CrawfordCurrie
The copyright of the content on this website is held by the contributing authors, except where stated elsewhere. See Copyright Statement. Creative Commons License    Legal Imprint    Privacy Policy