Extension.LoadFunction, Now With Enhanced Error Reporting!

, ,

Ever had a syntax error in a .pqm file? Likely, the error’s message described the problem but did not tell you which .pqm file contained the error. Instead, you may have had to peruse the various recently-edited .pqm files in your connector to figure out which one the problem originated from.

Thankfully, there is a way to improve this experience, so that extension module load errors identify the problematic source file!

Old-School: Anonymous Errors

Organizing helper functions into .pqm files is common in custom connector projects. The traditional way to import a function (or other value) from a .pqm file into the extension’s main environment is to read the .pqm’s contents as text into a variable, then perform an Expression.Evaluate on the just-read text using the below template:

Extension.LoadFunction = (name as text) =>
  let
    binary = Extension.Contents(name),
    asText = Text.FromBinary(binary)
  in
    Expression.Evaluate(asText, #shared);

// Above previously live on learn.microsoft.com
// Reference link: https://github.com/MicrosoftDocs/powerquery-docs/commit/c9a70dda09604aefcc4477bb227127f8ffadd8f6#diff-55970e823a2405d94c78747576475f13cf0f1d09e7cdb63e7e65ad86382c1544L251-L256

If the evaluation attempt dies with a syntax error, that error will be dutifully reported. However, its message does not identify the .pqm file containing the error.

Error from old school Extension.LoadModule
Looking at the above, can you tell which .pqm file the error came from?

Enhanced: Improved Error Reporting

This lack of information about the error’s origin is easy to rectify by having the “load .pqm” logic catch the evaluate error, wrap it with details identifying the error’s origin, then raise the enhanced (wrapped) error.

Extension.LoadFunction = (fileName as text) =>
  let
      binary = Extension.Contents(fileName),
      asText = Text.FromBinary(binary)
  in
      try
        Expression.Evaluate(asText, #shared)
      catch (e) =>
        error [
            Reason = "Extension.LoadFunction Failure",
            Message.Format = "Loading '#{0}' failed - '#{1}': '#{2}'",
            Message.Parameters = {fileName, e[Reason], e[Message]},
            Detail = [File = fileName, Error = e]
        ];

With these changes in place, if a .pqm file contains a syntax error, the error message presented to you clearly identifies the source of the error:

Error from error-enhanced Extension.LoadModule

This revised Expression.LoadFunction was published live last week in Microsoft’s docs.

However, its presence there doesn’t revise existing connectors to use it. If you have existing extension/custom connector projects that load from .pqm files, consider updating them to reflect this enhanced version of Expression.LoadFunction.


Kudos to Matt Masson from the Power Query team who suggested this approach!

Leave a Reply

Your email address will not be published. Required fields are marked *