Home Server
New Blog Posts: Merging Reports - Part 1 and Part 2

Access Violations for Volume Data Module - D6 RB10.04 W2K

edited September 2006 in Server
Hi

I am in the process of constructing my server and need to access queries
etc. on the datamodule that I am using for my TrsReportExplorerVolume.
Whenever I try this I get an access violation even though the data module
has been created.

Is the report server doing something with this datamodule that could cause
an access violation?

I want to do several things with the datamodule

Allow configuration of the ORACLE session user/password/server so no
need to hardcode values

CatalogUserName := dmExplorerDB.sesExplorerTables.Username;
CatalogPassword := dmExplorerDB.sesExplorerTables.Password;
CatalogServer := dmExplorerDB.sesExplorerTables.Server;

Check that a user exists on the database in response to a
ValidateSessionParameters event

with dmExplorerDB.qryValidUser do
try
Params.ParamValues['usr_id'] := AUserId;
ExecSQL;
// If we have a record then the user exists
Result := RecordCount = 1;
except
Result := False;
end;

I have a beforePublishReport event on the volume which executes a stored
proc and that works fine. Do you have any idea what is going on here?

Comments

  • edited September 2006

    - Try running the server application within the Delphi debugger so that you
    can trace your code.

    - Add try..except blocks around your code that can re-raise the exception as
    a desendant of EReportBuilder - see tech tip below.

    - I do not understand the first section of code, where is this executed -
    what event? And what is CatalogUserName, etc.

    - For the second section of code, I do not notice anything. It is probably
    safer to set qury.Active to False prior to setting any params, etc. We no
    longer use the With statement in RB source code because it sometimes lead to
    unexpected results.



    -------------------------------------------------------------------------------
    Tech Tip: RB Server - Exception Handling
    -------------------------------------------------------------------------------

    ThiS article applies to processing that occurs on the report server. It does
    not apply to the webtier or client report.

    The report server is a multi-threaded application. Each report executes in a
    separate thread. Exceptions that descend from EReportBuilder are handled
    gracefully by the server - the exception is propogated back to the web tier
    or client report application. A web tier application will display an error
    page, a client report application will raise an exception in the client app.
    In both cases a descriptive message is included.

    An exception that does not descend from EReportBuilder error is considered
    fatal and will cause the server application to terminate. If ReportBuilder
    Services is being used to manage the server, then ReportBuilder Services
    will automatically try to restart the server application.

    ReportBuilder Server contains code to check for common exceptions that occur
    when loading and generating reports. These exceptions are re-raised as
    either EReportBuilder or a descendant of EReportBuilder error.


    Custom code that is added to the server should follow these same guidelines.

    Example:

    uses
    ppTypes;


    // define a custom exception class to use for all of your custom code

    ECustomReportBuilderError = class(EReportBuilderError);


    try
    {some processing here}

    except on E: EStreamError do

    raise ECustomReportBuilderErrorr.Create(E.Message);

    end;


    Note: The above example will trap an EStreamError and re-raise it as
    ECustomReportBuilderError. Other exceptions will be considered fatal.
    Therefore you will have to decide which exceptions are acceptable and which
    are fatal.




    --
    Nard Moseley
    Digital Metaphors
    www.digital-metaphors.com



    Best regards,

    Nard Moseley
    Digital Metaphors
    www.digital-metaphors.com
  • edited September 2006
    Nard

    I only use 'with' in short snippets like the one here. I must say I never
    had a problem with it.

    In my other applications if I want to use something in a datamodule I add it
    to my uses clause and then refer to it by the module name

    i.e.

    use dmMyModule
    ..
    ..
    myModule.table1.open;

    All is fine. If I try the equivalent in the report server I get an access
    violation.

    If I inspect the object with the debugger I get properties with NULL values
    such as NAME which should be the name of the table or query (table1 in the
    above).

    The examples I gave are attempting to read the ODAC session for the
    username,password,server so I can maintain them in a dialog and not hard
    code them. Again, I can easily do this in every other app I have ever
    written but this one does not work.

    I have traced the code and the datamodule is destroyed on startup is this
    what the report server does?

    regards
    Andrew


  • edited September 2006
    Hi

    It is that. The module is destroyed and then created for each thread. I have
    adjusted my code and it all now works.


  • edited September 2006

    - the server application is a multi-threaded application that manages
    concurent client sessions.

    - each client session will have a separate instance of the report volume
    datamodule. The report volume datamodule acts as a thread-safe container for
    handling client requests - including executing reports.

    - the report volume datamodule that appears in the server project's
    auto-create list is used at startup to register the volume with the report
    catalog. The auto-create instance is then free'd.



    --
    Nard Moseley
    Digital Metaphors
    www.digital-metaphors.com

    Best regards,

    Nard Moseley
    Digital Metaphors
    www.digital-metaphors.com
This discussion has been closed.