query_script_try_catch

QueryScript Flow Control: try-catch statement

SYNOPSIS

try
  statement;
catch
  statement;

DESCRIPTION

try-catch is an error handling flow control structure. Flow is determined based on the appearance or non-appearance of execution errors.

The try statement (or block of statements) is executed. If no error occurs, it completes, and the catch statement is never executed.

If an error is detected within execution of the try statement, the try statement is aborted at the point of error (i.e. all statements following the point of error are discarded), and the catch statement (or block of statements) is executed.

An error thrown from within a catch is not further caught, unless surrounded in itself by a nested try-catch statement.

The catch block executes upon any error thrown within the try statement. It is not possible, at the moment, to explicitly specify a type of error for which the catch block should operate. Nor is it possible to specify multiple catch blocks as is common in various programming languages.

Furthermore, it is currently not possible to retrieve the exact error (or error code) causing the catch block to operate. All that is known is that some error has been raised.

Empty statements are not allowed in QueryScript. However, empty blocks are, and the try-catch clause may be followed by an empty block, or by the do-nothing pass statement.

Though syntactically valid, it makes no sense to use an empty try statement. It does make perfect sense to use an empty catch statement, to the result of silencing an error without termination of the script.

Nesting

It is possible to have nested try-catch statements. When nested, errors are caught by the deepest catch block which applies to them. To illustrate, consider:

try {
  statement1;
  try {
    statement2;
  }
  catch {
    -- errors in statement2 are handled here
    statement 3;
  }
  statement 4;
}
catch {
  -- errors in statement1, statement3 and statement4 are handled here
  -- errors in statement2 are not handled here
  statement 5;
}

Unlike other common implementations of try-catch, QueryScript does not require block statements, i.e. braces. This allows for the following try all you can syntax, which is very similar to a nested if-else-if-else construct:

try {
  statement1;
}
catch try {
  -- We only get here if statement1 fails
  statement2;
}
catch try {
  -- We only get here if statement1 & statement2 fail
  statement3;
}
catch try {
  -- We only get here if all previous statements fail
  statement4;
}
catch {
  -- They all failed
  statement5;
}

EXAMPLES

Simulate a schema upgrade process: try and create a table. If it already exists, make sure a given column is upgraded to a desired type:

try
{
  -- Try and create table:
  CREATE TABLE test.article (
    article_id int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
    title varchar(128) CHARSET utf8,
    content text CHARSET utf8
  );
}
catch
{
  -- Apparently table already exists. Upgrade it:
  ALTER TABLE test.article
    MODIFY COLUMN content text CHARSET utf8;
}

Repeat attempts for query which is expected to abort on deadlock: insist on executing it until successful:

while (true)
{
  try
  {
    -- Attempt query which is expected to abort on deadlock:
    UPDATE some_table SET some_column = 1 WHERE some_condition;
    -- Got here? This means query is successful! We can leave now.
    break;
  }
  catch
  {
    -- Apparently there was a deadlock. Rest, then loop again until succeeds
    sleep 1;
  }
}

NOTE

Since it is impossible to know the nature of the error causing the catch block to execute, and since any error will cause it to execute, it is the user's responsibility to deduce the origin of the error. In particular, watch out for plain syntax error, or otherwise SQL errors, such as misspelling table or column names.

SEE ALSO

if-else, throw

AUTHOR

Shlomi Noach
 
common_schema documentation