Page 1 of 2

Guide: Create Custom Errors

Posted: 30 Jun 2012, 15:25
by Lapo
Hello,
this quick guide will show you a few easy steps to add any number of custom error codes. These can be used with the Login Handler to provide special login errors to the client. Make sure to run SFS2X version 2.0.1 or higher and let's get started!

» Server Side
Let's say we want to create our custom login handler and we will need two new custom errors:

    Invalid age: users below a certain age will not be allowed.
    Human verification test: to avoid bots, we'll add a question at login time to verify if the client is human or not.

First thing we will create a new Enum implementing the IErrorCode interface:

Code: Select all

import com.smartfoxserver.v2.exceptions.IErrorCode;

public enum MyCustomErrors implements IErrorCode
{
   AGE_IS_NOT_VALID(200),
   HUMAN_VERIFICATION_FAIL(201);
   
   private MyCustomErrors(int id)
   {
      this.id = (short) id;
   }
   
   private short id;
   
   @Override
    public short getId()
    {
       return id;
    }   
}

Please Note: we start with the error id at 200 in order to avoid collision with lower values that are already defined in the system

Next we create our basic Login Handler class:

Code: Select all

import com.smartfoxserver.v2.core.ISFSEvent;
import com.smartfoxserver.v2.core.SFSEventParam;
import com.smartfoxserver.v2.exceptions.SFSErrorData;
import com.smartfoxserver.v2.exceptions.SFSException;
import com.smartfoxserver.v2.exceptions.SFSLoginException;
import com.smartfoxserver.v2.extensions.BaseServerEventHandler;

public class CustomLoginHandler extends BaseServerEventHandler
{
   @Override
   public void handleServerEvent(ISFSEvent event) throws SFSException
   {
      String uName = (String) event.getParameter(SFSEventParam.LOGIN_NAME);
       SFSErrorData ed = new SFSErrorData(MyCustomErrors.HUMAN_VERIFICATION_FAIL);
       ed.addParameter(uName);
      
       throw new SFSLoginException("Wrong answer, are you human?", ed);
   }
}


For the sake of simplicity we just show here how to throw the LoginException with the new error code just created.
Please note that we are sending one extra parmeter, the name of the user attempting the login.

Finally, here's the code of the main extension file to complete the server side part:

Code: Select all

import com.smartfoxserver.v2.core.SFSEventType;
import com.smartfoxserver.v2.extensions.SFSExtension;

public class CustomErrorExtension extends SFSExtension
{
   @Override
   public void init()
   {
      addEventHandler(SFSEventType.USER_LOGIN, CustomLoginHandler.class);
   }
   
   @Override
   public void destroy()
   {
       super.destroy();
   }
}


» Client Side
On the client we just need to define the new code and provide a String in any language that will be used to compose the message.
This is how it is done in Actionscript 3. The same will also work in C#, Java, Objective-C etc...

Code: Select all

SFSErrorCodes.setErrorMessage(201, "Sorry {0}, you don't seem to be a human user. Nice try!")

The above code simply adds a new string, including the parameter placeholder. This message will be then provided in the LOGIN_ERROR event when the user will attempt to login.

Voilà! As simple as that! :D

Cheers
Lapo

Re: Guide: Create Custom Errors

Posted: 19 Jul 2012, 08:47
by Ferz
SFSErrorCodes.setErrorMessage(201, "Sorry {0}, you don't seem to be a human user. Nice try!")

This code causes error IndexOutOfRangeException: Array index is out of range if I use it in C#. It's very pitty. Can you provide some methods like AddErrorMessage ?

Re: Guide: Create Custom Errors

Posted: 22 Jul 2012, 17:16
by Lapo
In AS3 it works because internally the data structure is implemented via an Array which is dynamic. Probably in C# it is also implemented as an array but in this case they are final structures and cannot modified directly.
We will see how to introduce a method for adding those extra error codes at runtime.

thanks

Re: Guide: Create Custom Errors

Posted: 24 Jul 2012, 07:40
by Lapo
Little update: upon verification we have seen that the Java and C# API implement the error list as native arrays, therefore immutable.
We'll soon publish an update with the correction for both platforms.

Actionscript 3 and iOS API already work with this example

Re: Guide: Create Custom Errors

Posted: 04 Nov 2012, 17:20
by ThomasLund
This will be part of the next C# and Java APIs

Re: Guide: Create Custom Errors

Posted: 16 Dec 2012, 15:07
by alonew
Hi,I want to know,When can we use Custom Errors by Unity3d?

IndexOutOfRangeException: Array index is out of range if I use it in C#

my sfs2x version is 2.4.0 ,client version is 1.0.3(download link is 1.0.5 ,but it's version is 1.0.3 ?)

Re: Guide: Create Custom Errors

Posted: 17 Dec 2012, 09:07
by Lapo
You need to use the latest API, version 1.0.5.
Make sure you replace the API in your project and recompile the client

Thanks

Re: Guide: Create Custom Errors

Posted: 18 Dec 2012, 10:21
by alonew
hello, I use C# 1.0.5 Client .....Unity3d 4.0f7

I can Change the ErrorMessage,but can't added it.

the errormessage is
"argumentOutOfRangeException: argument is out of range"

so why?? does anyone has the same problem?

Re: Guide: Create Custom Errors

Posted: 20 Dec 2012, 11:46
by levancho
This solution does not seen to work when we deal with exstensionReponses, because in handlers,
we can not throw this kind of exceptions,
how to we gracefully deal with exception communication between client and server extension handlers?

Re: Guide: Create Custom Errors

Posted: 20 Dec 2012, 13:04
by rjgtav
I think the easiest way is to send a success boolean which value is false when an error happens on a ClientRequestHandler, alongside with the error's description.

Re: Guide: Create Custom Errors

Posted: 20 Dec 2012, 13:08
by levancho
well we did a little different way, right now
I am not sure if its best way but we have special command CMD_ERROR
and when error happens we send this to client along with info regarding which command error hapened at and additional optional params.

Code: Select all

  public void sendErrorCommand(String cmdName, SFSErrorData err, User recipient){
        SFSObject obj = new SFSObject();
        obj.putUtfString("command",cmdName);
        obj.putSFSObject("error",toSFSObject(err));
        send(CMD_ERROR,obj,recipient);
    }

Re: Guide: Create Custom Errors

Posted: 20 Dec 2012, 13:10
by rjgtav
Oh, yes, that's much better than my initial idea. ;)

Re: Guide: Create Custom Errors

Posted: 14 Jan 2013, 16:23
by anniyan137
Hi Lapo,

I followed this tutorial and created my custom error code too. I even tried this guide:
http://smecsia.me/blog/75/Smartfox+2X%3 ... ity+client

This works with the LoginError.

However, I am trying to restrict the user from joining a room if his money is less than the minimum amount. But I'm getting a SFSJoinRoomException is showing a stack trace on the server log when I try to throw my custom error.

I have got all the latest patches running on both the client and server side. I'm using Unity C# api. Any suggestions?

Thanks!

Re: Guide: Create Custom Errors

Posted: 15 Jan 2013, 16:32
by Lapo
However, I am trying to restrict the user from joining a room if his money is less than the minimum amount. But I'm getting a SFSJoinRoomException is showing a stack trace on the server log when I try to throw my custom error.

I don't think this will work for a join request from the client.

It would be much easier to use a public SFSGame room where you can attach a MatchExpression with the rules you want to check before joining the game. For more details check all the details about SFSGame and MatchExpression: http://docs2x.smartfoxserver.com/Advanc ... s/game-api

Re: Guide: Create Custom Errors

Posted: 16 Sep 2015, 16:16
by gabrielvpy
I can't seem to find a way to send an error to my client. I mean, I send an error this way:

In my handler:

Code: Select all

@Override
   public void handleClientRequest(User u, ISFSObject data) {
      ...
      try {
         //try to get stuff from my DB
      } catch (SQLException e) {
         e.printStackTrace();
          SFSErrorData err = new SFSErrorData(ZoneCustomErrors.ERROR_FINDING_DATA);
          MyExtension ext = (MyExtension) this.getParentExtension();
         ext.sendErrorCommand("mA", err, u);
      }
      ...
   }


In my extension:

Code: Select all

public void sendErrorCommand(String cmdName, SFSErrorData err, User recipient){
        SFSObject obj = new SFSObject();
        obj.putUtfString("command",cmdName);
        obj.putInt("error",err.getCode().getId());
        send(CMD_ERROR,obj,recipient);
    }


It seems like I'm creating a ZoneCustomError just to send an integer. I'm not sending a real error object. How do I send an error? I mean, how do I tell the server "this is an error, handle it" instead of handling it myself?