Pesquisar

Pergunta
· Fev. 7

Visual Studio Code eating licenses

Windows 10/Windows Server 2016:

I am currently monitoring our license use with a new rest-service I am implementing when I noticed my licenses on my instance being consumed and never released by Visual Studio Code.

For this I restarted my Instance, watched the licenses for a while, which remained at 1 during idle (I am guessing my MMGT Portal session uses 1) 
But when I connect to my Instance using Visual Studio Code (with my Instance setup in the extension already), suddenly 2 licenses are used. (I am guessing 1 for the "studio" and 1 for a terminal session, so far so good) 

But then when I open any file in the project, another license is used. 

All of them have User-IDs and the "CSP" type. No Grace time and stay active.  

So 3 licenses per active developer.

 

Now here's the problem:
If I do that on a new machine, with a InterSystems IRIS 2024.2 Entree - Concurrent Users for x86-64 (Microsoft Windows):5, Natural Language Processing (NLP), Develop license 

Even AFTER CLOSING VS Code, 2 of the 3 licenses are still in use. When I reopen VSCode, I get "service unavailable" because I ran out of licenses.

Is this normal behaviour? Do I need more than 5 licenses to program with 2 developers on a new machine? 

  

4 Comments
Discussão (4)4
Entre ou crie uma conta para continuar
Artigo
· Fev. 7 6min de leitura

IRIS %Status and Exceptions Part-2

In this article, exceptions are covered.

Working with Exceptions

Instead of returning a %Status response, you can raise and throw an Exception. You are then responsible for catching the exception and validating it. IRIS provides five main classes to handle exceptions effectively. Additionally, you can create custom exception class definition based on your needs.

These exceptions are different from %Status, so you can't directly/efficiently use the exception object with $SYSTEM.OBJ.DisplayError() or $SYSTEM.Status.DisplayError(). Instead, use the DisplayString() method to display the exception message Alternatively, you can convert the exception to %Status using the AsStatus() method and use the display methods mentioned above.

All exceptions inherit from %Exception.AbstractException. When you instantiate the object, use the %OnNew() callback method to set values since the formal parameters are common.

Set exception = ##Class(%Exception.General).%New(pName, pCode, pLocation, pData, pInnerException)

Where:

  • pName - is the Name is the name of the error(error message).
  • pCode - is the error code (like $$$GeneralError, $$$NamespaceDoesNotExist, or custom numbers when using a general exception).
  • pLocation - is the location where the error occurred.
  • pData - Data is extra information supplied for certain errors.
  • pInnerException - is an optional inner exception.

Let's continue with the 5 major exceptions

%Exception.SystemException

This exception is raised when a system process terminates with an error. IRIS raises this system error by default. Additionally, $ZERROR and $ECODE are defined when this exception is raised.

ClassMethod SystemException()
{
    Set $ECODE=""
    Set $ZREFERENCE=""
    Set $ZERROR=""
    Try {
        Write ^(1)
    }
    catch ex {
        Write $ECODE,!
        Write $ZERROR,!
        Write ex.DisplayString()
    }
}


Result

LEARNING>Do ##class(Learning.myexcept).SystemException()
,M1,
<NAKED>SystemException+5^Learning.myexcept.1
<NAKED> 30 SystemException+5^Learning.myexcept.1
LEARNING>

 

%Exception.StatusException

This Exception behaves similarly to the %Status type exception. You can raise it using various macros, such as 

  • $$$THROWONERROR(%sc,%expr) - execute the expression, set into %sc and throw exception
  • $$$ThrowOnError(%expr) -  execute the expression, set into %sc internally and throw exception
  • $$$TOE(%sc,%expr) - Invoke $$$THROWONERROR(%sc,%expr)
  • $$$ThrowStatus(%sc) - Directly throw the exception

Most commonly used method to raise this exception is "CreateFromStatus" which accepts the %Status as a argument and convert into StatusException

ClassMethod StatusException()
{
	Set sc1 = $$$ERROR($$$UserCTRLC) 
	#dim sc As %Exception.StatusException = ##class(%Exception.StatusException).CreateFromStatus(sc1)
	#; display the error message
	Write sc.DisplayString()
	
	#; convert to %Status again
	Set st = sc.AsStatus()
	Do $SYSTEM.Status.DisplayError(st)
}

Result 

LEARNING>Do ##class(Test.Exception).StatusException()
ERROR #834: Login aborted
ERROR #834: Login aborted

 

%Exception.SQL

This Exception handles SQL errors, using SQLCODE and %msg values. There are two methods to create this exception

Example:
either way you can raise an exception

  •  $$$ThrowSQLCODE(%sqlcode,%message)
  • ##class(%Exception.SQL).CreateFromSQLCODE(%sqlcode,%message)

CreateFromSQLCODE : The first parameter is the SQL code, and the second is the message.
 

ClassMethod SQLExceptionBySQLCODE()
{
    Set tSQLException = ##class(%Exception.SQL).CreateFromSQLCODE(-30,"SAMPLE.PERSON1 not found")
    Write tSQLException.DisplayString(),!
    Set st = tSQLException.AsStatus()
    Do $SYSTEM.Status.DisplayError(st)
}

Create object instance: Create an instance of the exception and then handle it.

ClassMethod GeneralException()
{
    Set ex1 = ##class(%Exception.General).%New(,5001)  ; just for inner exception
    Set exGen = ##class(%Exception.General).%New("RegistrationException",5852,,"Invalid MRN",ex1)
    Write exGen.DisplayString()
    Set sc = exGen.AsStatus()
    Do $SYSTEM.OBJ.DisplayError(sc)
}

%Exception.PythonException

This Exception provides Python error information. Here is the simplified sample.

ClassMethod pythonException()
{
    Try{
        Do ..pyTest()
    }
    Catch ex {
        Write $classname(ex)_"  "_ex.DisplayString()
    }
}
ClassMethod pyTest() [ Language = python ]
{
    print(1/0)
}

Result 

LEARNING>Do ##class(Learning.myexcept).pythonException()
%Exception.PythonException  <PYTHON EXCEPTION> 246 <class 'ZeroDivisionError'>: division by zero
 
ERROR #5002: ObjectScript error: <PYTHON EXCEPTION> *<class 'ZeroDivisionError'>: division by zero1

 

Last but not least

Custom Exception classes

For application-specific errors, it's crucial to handle exceptions precisely. Incorporate string localization on error messages. You can create custom Exception class.

For instance, you can create custom error messages with different translations based on the session's language.

^IRIS.Msg("MyApp")="en"
^IRIS.Msg("MyApp","en",62536)="InvalidMRN"
^IRIS.Msg("MyApp","ru",62536)="недействительный MRN"
 

Simplified custom Exception class sample

 
MyApp.Exception

 

 
MyApp.Errors.inc

Execution of the custom exception

This method demonstrates how to raise and display custom exceptions in different languages, including English and Russian

Include MyApp.Errors
Class MyApp.Utils Extends %RegisteredObject
{
    ClassMethod CustomExpcetionInEng()
    {
        Set tmyappException = ##class(MyApp.Exception).%New(,$$$InvalidMRN)
        wWritetmyappException.DisplayString()
    }

    ClassMethod CustomExpcetionInRussian()
    {
        Do ##class(%MessageDictionary).SetSessionLanguage("ru")
        Set tmyappException = ##class(MyApp.Exception).%New(,$$$InvalidMRN)
        write tmyappException.DisplayString()
    }
}

 Results 

LEARNING>d ##Class(MyApp.Utils).CustomExpcetionInEng()
InvalidMRN 62536
LEARNING>d ##Class(MyApp.Utils).CustomExpcetionInRussian()
недействительный MRN 62536
LEARNING>

Conclusion

In these ways you can handle the exceptions and %Status errors efficiently in your application code. Handling the errors effectively extremely helps in many ways!

Discussão (0)1
Entre ou crie uma conta para continuar
Pergunta
· Fev. 7

Need Help to do a connection Between IRIS and SAP RFC

Hello,

Please we need some help in connecting IRIS to SAP RFC.

We would appreciate if anyone has a detailed documentation for it. 

Thank you

2 Comments
Discussão (2)1
Entre ou crie uma conta para continuar
Anúncio
· Fev. 7

Autores destacados de la Comunidad de Desarrolladores de InterSystems de 2024

¡Hola desarrolladores!

Es hora de anunciar a los Autores Destacados de la Comunidad de Desarrolladores de InterSystems de 2024 🎉

Nos complace premiar a los contribuyentes más activos en todos los sitios regionales de la comunidad (EN, ES, PT, JP, CN y FR):

  • Revelación del Año
  • Autores Best-Seller
  • Top Expertos
  • Líderes de Opinión Más Destacados

¡Echémosle un vistazo al Muro de la Fama 2024 de la Comunidad de Desarrolladores y demos un gran aplauso a todos! 👏

Nombre de la insignia Ganadores DC Ganadores InterSystems
 
Nominación: Revelación del Año
Revelación de 2024

  

@john.smith4237

@Meenakshi Muthu

@Eyal Levin

@Alin Soare

@Veerraju Grandhi

@Takao Otokita

@Maxim Gorshkov

@Nicole Sun

@Brad Nissenbaum

@Shuheng Liu

 
Nominación: Autor Best-Seller
1er lugar
Oro al autor best-seller

  

@Muhammad Waseem

@Luis Angel Pérez Ramos

2do lugar 
Plata al autor best-seller

  

@Robert Cemper

@Megumi Kakechi

3er lugar
Bronce al best seller

  

@Iryna Mykhailova

@Hiroshi Sato

Autor Best Seller

  

@Heloisa Paiva

@Pierre LaFay

@David Hockenbroch

@姚 鑫

@sween

@Kurro Lopez

@Yuri Marx

@Mihoko Iijima

@Alberto Fuentes

@Sylvain Guilbaud

@Guillaume Rongier

@Toshihiko Minamoto

@Ricardo Paiva

@Danusa Calixto

 
Nominación: experto InterSystems
1er lugar:
Oro al experto DC

  

@Enrico Parisi

@Luis Angel Pérez Ramos

2do lugar:
Plata al experto DC

  

@Robert Cemper

@Alexander Koblov

3er lugar
Bronce al experto DC

  

@Jeffrey Drumm

@Brett Saviano

Experto DC

  

@Julius Kavay 

 @John Murray

@David Hockenbroch

@Ashok Kumar T

@Robert Barbiaux

@Stephen Canzano

@Yaron Munz

@Eduard Lebedyuk 

@Ben Spead 

@Timo Lindenschmid 

@Guillaume Rongier 

@Timothy Leavitt 

@Sylvain Guilbaud 

@Tani Frankel  

 
Nominación: líder de opinión de IS.
1er lugar:
Oro a líder de opinión

  

@Robert Cemper

@Luis Angel Pérez Ramos

2do lugar:
Plata a líder de opinión

  

@Iryna Mykhailova

@Sylvain Guilbaud

3er lugar:
Bronce a líder de opinión

  

@Enrico Parisi

@Guillaume Rongier

DC Opinion Leader

  

@Muhammad Waseem

@Pierre LaFay

@Heloisa Paiva

@Kurro Lopez

@David Hockenbroch

@John Murray

@Yuri Marx

@Julio Esquerdo

@Ben Spead

@Timothy Leavitt

@Danusa Calixto

@Eduard Lebedyuk

@Evgeny Shvarov

@Mihoko Iijima

@Hiroshi Sato

 

Esta lista es una buena razón para empezar a seguir a algunos de los grandes autores de la Comunidad de Desarrolladores ;)

¡UN GRAN APLAUSO A NUESTROS GANADORES!

¡Enhorabuena a todos y gracias por vuestras grandes contribuciones a la Comunidad de Desarrolladores de InterSystems en 2024! 

Discussão (0)1
Entre ou crie uma conta para continuar
Artigo
· Fev. 7 4min de leitura

IRIS %Status and Exceptions

You may encounter errors during any point of program execution, and there are several ways to raise and handle these exceptions. In this article, we'll explore how exceptions are handled efficiently in IRIS.

One of the most commonly used return types is %Status, which is used by methods to indicate success or failure. Let's begin by discussing %Status values.

Working with %Status

The %Status return type is used to represent errors or success. Many system methods return %Status when an error occurs. You can create a similar structure for your application errors, or convert to %Status, even when you raised exceptions  in your code.

Let's start creating the errors

Macros

When we talked about errors the Macros are essential and easy to create Status values in the code. IRIS provides several macros to create and handle errors within your application code.

The most commonly used macro is $$$ERROR.

$$$ERROR

The $$$ERROR macro specifically designed to generate and return a %Library.%Status value. It is your responsibility to check the status before continuing execution in your program. This macro is tightly coupled with general system errors. Keep the following points in mind when using this macro:

- The first argument (error codes) refers to general error codes inside the %occErrors include file.
- If you're using predefined errors from that include file, you can use the macro directly, with or without additional arguments.

Note: Before proceeding $SYSTEM.OBJ.DisplayError(status) or $SYSTEM.Status.DisplayError(status) used to display the error(s) and supports string localization 

Set sc = $$$ERROR($$$NamespaceDoesNotExist,"TEST")
Do $SYSTEM.OBJ.DisplayError(sc)

output: ERROR #5015: Namespace 'TEST' does not exist1
Set sc = $$$ERROR($$$UserCTRLC)
Do $SYSTEM.OBJ.DisplayError(sc)

ouput: ERROR #834: Login aborted1

If you use any other error code not listed in %occErrors, an "Unknown status code" error will be returned. Always use the predefined errorcode $$$GeneralError == 5001 for general error messages.

Unknown status code sample

Set sc = $$$ERROR(95875,"TEST Error")
Do $SYSTEM.Status.DisplayError(sc)

output: ERROR #95875: Unknown status code: 95875 (TEST Error)
Set sc = $$$ERROR($$$GeneralError,"TEST Error")
Do $SYSTEM.OBJ.DisplayError(sc)

output: ERROR #5001: TEST Error

$$$ADDSC

The %Status doesn't necessarily hold only one error. Your program can validate multiple conditions and keep track of all errors in a single status, then use the $$$ADDSC macro. For example, the %ValidateObject() method can return multiple errors in a single response, which uses this functionality.

The $$$ADDSC macro appends one status to another, and the $SYSTEM.Status.AppendStatus method performs the same function.

$$$ADDSC(sc1,sc2) / $SYSTEM.Status.AppendStatus(s1,s2) - append sc2 to sc1 and return a new status code.

ClassMethod AppendErrors()
{
    Set sc1 = $$$ERROR($$$UserCTRLC) 
    Set sc2 = $$$ERROR($$$NamespaceDoesNotExist,"TEST")
    Set sc = $$$ADDSC(sc1,sc2)
    Do $SYSTEM.Status.DisplayError(sc)
    Write !
    Set sc = $$$ADDSC(sc1,sc2)
    Do $SYSTEM.Status.DisplayError(sc)
}
output
LEARNING>do ##class(Learning.ErrorHandling).AppendErrors()
 
ERROR #834: Login aborted
ERROR #5015: Namespace 'TEST' does not exist
 
ERROR #834: Login aborted
ERROR #5015: Namespace 'TEST' does not exist

both results are same!

$$$GETERRORCODE

$$$GETERRORCODE(status) - Returns the error code value from the Status . This macro is belongs from the %occStatus.inc

    Set status = $$$ERROR($$$UserCTRLC) 
    Write $$$GETERRORCODE(status),!
    #;output: 834
    Set status = $$$ERROR($$$GeneralError,"TEST Error")
    Write $$$GETERRORCODE(status)
    #;output: 5001

$$$GETERRORMESSAGE
$$$GETERRORMESSAGE(sc,num) - This macro is returns the portion of the error based on the num in the %Status 
Here is an example.
 

ClassMethod GetErrorMsgMacro()
{
	Set status = $$$ERROR($$$GeneralError,"TEST Error",1,$$$ERROR($$$GeneralError,"TEST Error2"))
	write $$$GETERRORMESSAGE(status),! ; It prints "TEST Error"
	#;
	Set st = $$$GETERRORMESSAGE(status,3) ; it get the "$$$ERROR($$$GeneralError,"TEST Error2")" in 3rd position based on the 2nd argument 
	write $$$GETERRORMESSAGE(st),! ; it prints TEST Error2
}

LEARNING>Do ##class(Learning.myexcept).GetErrorMsgMacro()
TEST Error
TEST Error2

 

Validate Return Status

Now that you've created the error and returned it to your program, the next step is validating whether the return response is successful or erroneous.

The $$$ISERR macro checks whether the status represents an error. It returns 1 if the status indicates an error, otherwise it returns 0. There's another macro, $$$ISOK, which returns 1 when the status is successful.

Displaying Errors

If your program unexpectedly errors out (always expect the unexpected), you need to display the error message. The %SYSTEM.Status class is specifically designed for viewing or creating %Status values (if you prefer not to use macros) and we already seen the samples above.

Here are equivalent methods in %SYSTEM.Status that replace the macros:

Macro Methods
$$$ISERR $SYSTEM.Status.IsError()
$$$ISOK $SYSTEM.Status.IsOK()
$$$ADDSC $SYSTEM.Status.AppendStatus()
$$$ERROR $SYSTEM.Status.Error()
$$$OK $SYSTEM.Status.OK()
$$$GETERRORCODE $SYSTEM.Status.GetErrorCodes()

The Exceptions will be continued in the next article.

Discussão (0)1
Entre ou crie uma conta para continuar