1
votes

How do you handle error conditions in a Mediawiki Extension?

I have written an extension that uses a couple of stored procedures to retrieve data from a SQL Server table.

It all works fine until the DB or the server is offline, at which point the mssql_connect call fails. I've tried numerous methods of dealing with this but each one either fails with an error 500 or some error text on an otherwise blank page, both stopping the wiki page from loading. I would like it to fail gracefully and allow the rest of the wiki page to load correctly.

I know I am missing something obvious, any ideas?

Below is the code I am using to connect to the DB and return the values to the page:

function RetrieveFromDatabase( $sproc, $spparam )
{
    $usr =  "usr";
    $pwd =  "pwd";
    $db =   "BGInfo";
    $host = "server";
    $output = "";

    // connect to database
  $con = mssql_connect ($host, $usr, $pwd);
  mssql_select_db($db);

  /* prepare the statement resource */
  $stmt=mssql_init($sproc, $con);

  if (isset($spparam))
  {
    mssql_bind($stmt, '@MachineName',    $spparam,  SQLVARCHAR);
  }

  /* now execute the procedure */
  if ($result = mssql_execute($stmt))
  {
    return $result;
  }
  else
  {
    return NULL;
  }
}

function GetMachineTotalStorageInTBRender( $input, $args, $parser )
{
    $parser->disableCache();

    $output = "";

    $result = RetrieveFromDatabase("TotalDriveSpaceByMachine", $input);
  if ($result)
  {
    while($row = mssql_fetch_array($result))
    {
      // Assign Variables
      $TotalTB = $row["TB"];
      if(!is_null($TotalTB))
      {
        // Print Variables in Table
        $output = $TotalTB." TB";
      }
    } // End While Loop
  } // End If

    return $output;
}
2

2 Answers

1
votes

First of all, surround the mysql_connect() call in error suppression like this:

wfSuppressWarnings();
$con = mssql_connect ($host, $usr, $pwd);
wfRestoreWarnings();

Second, check $con and bail out early to prevent fatals.

1
votes

Thanks to MaxSem and Samuel Lampa for your help. The answer (for me at least) was to wrap the connect to database section in a try catch, this allowed the connection to be attempted and when it failed to fall back out gracefully. It should probably report an error back to the user and/or logs but this is for my home use only so it's not a big deal.

function RetrieveFromDatabase( $sproc, $spparam )
{
    $usr =  "usr";
    $pwd =  "pwd";
    $db =   "BGInfo";
    $host = "server";
    $output = "";

  try
  {
    // connect to database
    $con = mssql_connect ($host, $usr, $pwd);
  }
  catch(ExprError $e)
  {
      return NULL;
  }

  if (!$con)
  {
      return;
  }

  try
  {
    mssql_select_db($db);
  }
  catch(ExprError $e)
  {
      return NULL;
  }

  /* prepare the statement resource */
  $stmt=mssql_init($sproc, $con);

  if (isset($spparam))
  {
    mssql_bind($stmt, '@MachineName',    $spparam,  SQLVARCHAR);
  }

  /* now execute the procedure */
  if ($result = mssql_execute($stmt))
  {
    return $result;
  }
  else
  {
    return NULL;
  }
}

function GetMachineTotalStorageInTBRender( $input, $args, $parser )
{
    $parser->disableCache();

    $output = "";

    $result = RetrieveFromDatabase("TotalDriveSpaceByMachine", $input);
  if ($result)
  {
    while($row = mssql_fetch_array($result))
    {
      // Assign Variables
      $TotalTB = $row["TB"];
      if(!is_null($TotalTB))
      {
        // Print Variables in Table
        $output = $TotalTB." TB";
      }
    } // End While Loop
  } // End If

    return $output;
}