Item8908: Fatal error in WorkflowPlugin
Priority: Urgent
Current State: Closed
Released In:
Target Release: n/a
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